rm(list = ls())
library(tidyverse)
Warning: package ‘tidyverse’ was built under R version 3.6.2
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
── Attaching packages ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse 1.3.1 ──
✓ ggplot2 3.3.5     ✓ purrr   0.3.4
✓ tibble  3.1.2     ✓ dplyr   1.0.7
✓ tidyr   1.1.3     ✓ stringr 1.4.0
✓ readr   1.4.0     ✓ forcats 0.5.1
Warning: package ‘ggplot2’ was built under R version 3.6.2
Warning: package ‘tibble’ was built under R version 3.6.2
Warning: package ‘tidyr’ was built under R version 3.6.2
Warning: package ‘readr’ was built under R version 3.6.2
Warning: package ‘purrr’ was built under R version 3.6.2
Warning: package ‘dplyr’ was built under R version 3.6.2
Warning: package ‘forcats’ was built under R version 3.6.2
── Conflicts ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()
library('svglite')
Warning: package ‘svglite’ was built under R version 3.6.2
library(broom)
Warning: package ‘broom’ was built under R version 3.6.2
library(purrr)
library(lemon)
Warning: package ‘lemon’ was built under R version 3.6.2

Attaching package: ‘lemon’

The following object is masked from ‘package:purrr’:

    %||%

The following objects are masked from ‘package:ggplot2’:

    CoordCartesian, element_render
library(pracma)

Attaching package: ‘pracma’

The following object is masked from ‘package:purrr’:

    cross
library(lubridate)
Warning: package ‘lubridate’ was built under R version 3.6.2

Attaching package: ‘lubridate’

The following objects are masked from ‘package:base’:

    date, intersect, setdiff, union
library(plotrix)
Warning: package ‘plotrix’ was built under R version 3.6.2
library(lme4)
Warning: package ‘lme4’ was built under R version 3.6.2
Loading required package: Matrix

Attaching package: ‘Matrix’

The following objects are masked from ‘package:pracma’:

    expm, lu, tril, triu

The following objects are masked from ‘package:tidyr’:

    expand, pack, unpack
library(lmerTest)
Warning: package ‘lmerTest’ was built under R version 3.6.2

Attaching package: ‘lmerTest’

The following object is masked from ‘package:lme4’:

    lmer

The following object is masked from ‘package:pracma’:

    rand

The following object is masked from ‘package:stats’:

    step
library(car)
Loading required package: carData
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
Registered S3 methods overwritten by 'car':
  method                          from
  influence.merMod                lme4
  cooks.distance.influence.merMod lme4
  dfbeta.influence.merMod         lme4
  dfbetas.influence.merMod        lme4

Attaching package: ‘car’

The following object is masked from ‘package:pracma’:

    logit

The following object is masked from ‘package:dplyr’:

    recode

The following object is masked from ‘package:purrr’:

    some
library(sjstats)
Warning: package ‘sjstats’ was built under R version 3.6.2

Attaching package: ‘sjstats’

The following object is masked from ‘package:broom’:

    bootstrap
call_aesthethics <- function(text_size){
  
  th <- theme(   panel.grid.major = element_blank(),
                 panel.grid.minor = element_blank(),
                 panel.border = element_blank(),
                 panel.background = element_blank(),
                 axis.line = element_line(size = 0.5), 
                 legend.position = 'right', 
                 legend.text = element_text(size= text_size, family="Helvetica"),
                 text = element_text(size= text_size, family="Helvetica"), 
                 strip.text.x = element_text(size = rel(0.90)), 
                 strip.text.y = element_text(size = rel(0.90)), 
                 axis.title.x = element_text(vjust=-0.3), 
                 plot.title = element_text(hjust = 0.5, vjust = 0), 
                 axis.ticks = element_line(size = 0.4), 
                 axis.text.x.bottom  = element_text(size = rel(0.90), margin = unit(c(t = 2.5, r = 0, b = 0, l = 0), "mm")),
                 axis.title.y = element_text(vjust = 1),
                 axis.text.y = element_text(size = rel(0.90), margin = unit(c(t = 0, r = 2.5, b = 0, l = 0), "mm")),
                 axis.ticks.length = unit(-1.2, "mm"),
                 axis.text.x.top = element_text(size = rel(0.90), margin = unit(c(t = 0, r = 0, b = 2.5, l = 0), "mm")))
  
  return(th)
}

my.colors2 <-  c("#006600", "#800080", "#FF9900", 'deepskyblue4')
th <- call_aesthethics(16)

# baseline subtraction function
baseline_subtract <- function(my.data, base_cn_start, base_cn_end, returnAngle){
  
  
  my.subjects <- unique(my.data$SN)
  counter <- 1
  mybaseline <- setNames ( data.frame(matrix(NaN, nrow = length(my.subjects) * 12, ncol = 5)), 
                           c('SN', 'ti', 'Hand_base', 'RT_base','Return_base'))
                                                    
  for(si in my.subjects){
    
    idx <- my.data$SN == si
      
    for(mi in unique(my.data$ti[idx])){
      
      idx_sub <- my.data$SN == si & my.data$ti == mi
      idx_bl <- my.data$SN == si & my.data$ti == mi & 
        my.data$CN >= base_cn_start & my.data$CN <= base_cn_end
      
      sub_Hand_mean <- mean(my.data$Hand[idx_bl], na.rm = TRUE)
      my.data$Handb[idx_sub] <- my.data$Hand[idx_sub] - sub_Hand_mean
      
      sub_RT_mean <- mean(my.data$RT[idx_bl], na.rm = TRUE)
      my.data$RTb[idx_sub] <- my.data$RT[idx_sub] - sub_RT_mean
      
      if(returnAngle == 1){
        sub_Return_mean <- mean(my.data$ReturnAngle[idx_bl], na.rm = TRUE)
        my.data$ReturnAngleb[idx_sub] <- my.data$ReturnAngle[idx_sub] - sub_Return_mean
        mybaseline$Return_base[counter] <- sub_Return_mean
      }
      
      mybaseline$SN[counter] <- si
      mybaseline$ti[counter] <- mi
      mybaseline$Hand_base[counter] <- sub_Hand_mean
      mybaseline$RT_base[counter] <- sub_RT_mean
      counter <- counter + 1
    }
  }
  
  return(list(my.data, mybaseline))
}


mainDir <- "~/Dropbox/VICE/JT/KIM_USEDEPENDENT/Figures"
subDir <- today()
figDir <- "~/Dropbox/VICE/JT/KIM_USEDEPENDENT/Figures/"
knitr::opts_knit$set(root.dir = figDir)
dir.create(file.path(mainDir, subDir), showWarnings = FALSE)

Renalaysis of V&S


VS.data <- as_tibble( read.csv("/Users/jonathantsay/Dropbox/MOTOR/use_dependent/use-dependent-learning/VerstynenSabes2011.csv", header = TRUE, sep = ',')) %>% mutate(Bias = Hand_IB)

VS Individual data



for(si in unique(VS.data$SN)){
  
  ind.plot <- VS.data %>% 
    filter(SN == si & Distance > 0) %>%  
    ggplot(aes(x = RT, y = Bias, group = factor(Distance))) + 
    geom_point(alpha = 0.4, aes(color = factor(Distance))) + 
    geom_smooth(method = 'lm', aes(color = factor(Distance)), size = 0.5, se = FALSE) + 
    #stat_cor(method = 'pearson')+ 
    facet_rep_wrap(.~Distance, repeat.tick.labels = TRUE) + 
    scale_color_manual(values = my.colors2[c(1, 2, 3)], guide = FALSE) + 
    labs(y = 'Inward Bias (°)', x = 'RT (s)') + #subtitle = sprintf('V&S Subject #%s', si) 
    th + theme(axis.text.x = element_text(angle = 45, hjust = 0.95), 
               legend.position = 'none') +
    scale_x_continuous(breaks = c(0.2, 0.4)) + 
    scale_y_continuous(breaks = seq(-50, 100, 50)) + 
    coord_capped_cart(ylim = c(-50, 100)) 
  print(ind.plot) 
  
  ggsave(sprintf('VS_SUB%s_notitle_%s.pdf', si,subDir), plot = ind.plot, height = 3, width = 6,  units = "in")
  
}
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
Warning: Removed 1 rows containing non-finite values (stat_smooth).
Warning: Removed 1 rows containing missing values (geom_point).
`geom_smooth()` using formula 'y ~ x'
Warning: Removed 1 rows containing non-finite values (stat_smooth).
Warning: Removed 1 rows containing missing values (geom_point).
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'

VS.group data


VS.data.ind <- VS.data %>%
  group_by(SN, Distance) %>%
  dplyr::summarise(bias_mean = mean(Bias, na.rm = TRUE), 
                   rt_mean = mean(RT, na.rm = TRUE))
`summarise()` has grouped output by 'SN'. You can override using the `.groups` argument.
VS.data.grp <- VS.data.ind %>%
  group_by(Distance) %>%
  dplyr::summarise(bias_grp_mean = mean(bias_mean, na.rm = TRUE), 
                   bias_stderr_mean = std.error(bias_mean, na.rm = TRUE), 
                   rt_grp_mean = mean(rt_mean, na.rm = TRUE), 
                   rt_stderr_mean = std.error(rt_mean, na.rm = TRUE)) %>%
  add_row(Distance = 0,  bias_grp_mean= 0, bias_stderr_mean = 0)

VS.grp <- VS.data.grp %>%
  mutate(groupvar = 1) %>%
  ggplot(aes(x = Distance, y = bias_grp_mean, group = groupvar)) + 
  geom_segment(aes(x=-5, xend=95, y = 0, yend = 0), color = 'lightgrey') +
  geom_point() + 
  geom_line() + 
  geom_errorbar(aes(ymin = bias_grp_mean - bias_stderr_mean, ymax = bias_grp_mean + bias_stderr_mean), width = 0.2) + 
  labs(y = 'Inward Bias (°)', x = 'Probe Distance (°)') +
  th + theme(axis.text.x = element_text(angle = 45, hjust = 0.95), 
             legend.position = 'none') +
  scale_y_continuous(breaks = seq(0, 25, 5)) + 
  scale_x_continuous(breaks = c(0, 30, 60, 90)) + 
  coord_capped_cart(ylim = c(-5, 25))
print(VS.grp)

ggsave(sprintf('VS_Group_%s.pdf', subDir), plot = VS.grp, height = 3, width = 4,  units = "in")

VS Quantile Analysis


VS.Quantile.plot <- VS.data %>%
  group_by(SN, Distance) %>%
  mutate(quantile = ntile(RT, 5)) %>%
  group_by(SN, Distance, quantile) %>%
  dplyr::summarise(bias_mean = mean(Bias, na.rm = TRUE), 
                   RT_mean = mean(RT, na.rm = TRUE)) %>%
  group_by(Distance, quantile) %>%
  dplyr::summarise(bias_grp_mean = mean(bias_mean, na.rm = TRUE), 
                   bias_std_err = std.error(bias_mean, na.rm = TRUE), 
                   RT_grp_mean = mean(RT_mean, na.rm = TRUE), 
                   RT_std_err = std.error(RT_mean, na.rm = TRUE)) %>%
  ggplot(aes(x = RT_grp_mean, y = bias_grp_mean, color = factor(Distance),group = factor(Distance))) + 
  geom_point() + 
  geom_line() + 
  geom_errorbarh(aes(xmax = RT_grp_mean + RT_std_err, xmin = RT_grp_mean - RT_std_err), alpha = 0.4)  +
  geom_errorbar(aes(ymax =bias_grp_mean + bias_std_err, ymin = bias_grp_mean - bias_std_err), alpha = 0.4) + 
  labs(y = 'Inward Bias (°)', x = 'RT (s)') +
  scale_color_manual(values = c("black", my.colors2[c(1, 2, 3)]), guide = FALSE) + 
  scale_x_continuous(breaks = seq(0.1, 0.5, 0.1)) + 
  theme(axis.text.x = element_text(angle = 45, hjust = 0.95), 
        legend.position = 'none') +
  th + 
  scale_y_continuous(breaks = c(0, 20, 40)) +
  coord_capped_cart(ylim = c(-5, 40),xlim = c(0.2, 0.5)) 
`summarise()` has grouped output by 'SN', 'Distance'. You can override using the `.groups` argument.
`summarise()` has grouped output by 'Distance'. You can override using the `.groups` argument.
print(VS.Quantile.plot)
Warning: Removed 1 rows containing missing values (geom_point).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 1 rows containing missing values (geom_errorbarh).
Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please use `guide = "none"` instead.
ggsave(sprintf('VS_Quantile_%s.pdf', subDir), plot = VS.Quantile.plot, height = 3, width = 4,  units = "in")
Warning: Removed 1 rows containing missing values (geom_point).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 1 rows containing missing values (geom_errorbarh).
Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please use `guide = "none"` instead.

VS Quintile Normalize RT-Bias Dependency


VS.Quantile.norm.plot <- VS.data %>%
  group_by(SN, Distance) %>%
  filter(Distance != 0) %>%
  mutate(Scale_HandIB = scale(Hand_IB)) %>%
  mutate(quantile = ntile(RT, 5)) %>%
  group_by(SN, Distance, quantile) %>%
  dplyr::summarise(bias_mean = mean(Scale_HandIB, na.rm = TRUE), 
                   RT_mean = mean(RT, na.rm = TRUE)) %>%
  group_by(Distance, quantile) %>%
  dplyr::summarise(bias_grp_mean = mean(bias_mean, na.rm = TRUE), 
                   bias_std_err = std.error(bias_mean, na.rm = TRUE), 
                   RT_grp_mean = mean(RT_mean, na.rm = TRUE), 
                   RT_std_err = std.error(RT_mean, na.rm = TRUE)) %>%
  ggplot(aes(x = RT_grp_mean, y = bias_grp_mean, color = factor(Distance),group = factor(Distance))) + 
  geom_point() + 
  geom_line() + 
  geom_errorbarh(aes(xmax = RT_grp_mean + RT_std_err, xmin = RT_grp_mean - RT_std_err), alpha = 0.4)  +
  geom_errorbar(aes(ymax =bias_grp_mean + bias_std_err, ymin = bias_grp_mean - bias_std_err), alpha = 0.4) + 
  labs(y = 'Inward Bias (norm)', x = 'RT (s)') +
  scale_color_manual(values = c(my.colors2[c(1, 2, 3)]), guide = FALSE) + 
  scale_x_continuous(breaks = seq(0.1, 0.5, 0.1)) + 
  theme(axis.text.x = element_text(angle = 45, hjust = 0.95), 
        legend.position = 'none') +
  th + 
  coord_capped_cart(ylim = c(-1, 1),xlim = c(0.2, 0.5)) 
`summarise()` has grouped output by 'SN', 'Distance'. You can override using the `.groups` argument.
`summarise()` has grouped output by 'Distance'. You can override using the `.groups` argument.
print(VS.Quantile.norm.plot)
Warning: Removed 1 rows containing missing values (geom_point).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 1 rows containing missing values (geom_errorbarh).
Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please use `guide = "none"` instead.
setwd("~/Desktop")
Warning: The working directory was changed to /Users/jonathantsay/Desktop inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
ggsave(sprintf('VS_Quantile_norm_%s.pdf', subDir), plot = VS.Quantile.norm.plot, height = 3, width = 4,  units = "in")
Warning: Removed 1 rows containing missing values (geom_point).
Warning: Removed 1 row(s) containing missing values (geom_path).
Warning: Removed 1 rows containing missing values (geom_errorbarh).
Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please use `guide = "none"` instead.

Import Experiment 1


E1.data <- as_tibble( read.csv("/Users/jonathantsay/Dropbox/MOTOR/use_dependent/use-dependent-learning/UD_E1.csv", header = TRUE, sep = ',') %>%
                        dplyr::select(SN:RTb, hand_theta_40)) %>% mutate(group = 1) %>%
  mutate(Distance_raw = as.double( abs(ti - trainTgt)), 
         Distance = case_when(Distance_raw > 180 ~ abs(Distance_raw - 360), 
                              Distance_raw < -180 ~ abs(Distance_raw + 360),
                              Distance_raw <= 180 & Distance_raw >= -180 ~ Distance_raw),
         CN = TN, 
         Hand = hand_theta_40, Handb = NaN, RTb = NaN)

E1.data.base.out <- baseline_subtract(E1.data, 71, 140, 0)
E1.data <- E1.data.base.out[[1]]
E1.data.base <- E1.data.base.out[[2]]


E1.data <- E1.data %>%
  mutate(Hand_IB = case_when(trainTgt == 60 & (ti == 90   | ti == 120  | ti == 150 ) ~ -Handb, 
                             trainTgt == 60 & (ti == 0   | ti == 30  | ti == 330 | ti == 60) ~ Handb, 
                             trainTgt == 150 & (ti == 180  | ti == 210  | ti == 240) ~ -Handb, 
                             trainTgt == 150 & (ti == 60   | ti == 90  | ti == 120 | ti == 150) ~ Handb))


  

Experiment 1 Individual Data


for(si in unique(E1.data$SN)){
  
  groupvar <- unique( E1.data$group[E1.data$SN == si] ) 
  myymin <- min( E1.data$RT[E1.data$SN == si & E1.data$block >= 3 & E1.data$fbi == 0] ) + 0.1
  myymax <- max( E1.data$RT[E1.data$SN == si & E1.data$block >= 3 & E1.data$fbi == 0] ) - 0.1
  
  ind.plot <- E1.data %>% 
    filter(SN == si & Distance != 0) %>%  
    filter(block >= 3 & fbi == 0 ) %>%
    ggplot(aes(x = RT, y = Hand_IB, group = factor(Distance))) + 
    geom_point(alpha = 0.4, aes(color = factor(Distance))) + 
    geom_smooth(method = 'lm', aes(color = factor(Distance)), size = 0.5, se = FALSE, linetype= groupvar) +
    #stat_cor(method = 'pearson')+ 
    facet_rep_wrap(.~Distance, repeat.tick.labels = TRUE, ncol = 4) + 
    scale_x_continuous(breaks = c(round(myymin, 1), round(myymax, 1) )) +
    scale_color_manual(values = c(my.colors2[c(1, 2, 3)]), guide = FALSE) + 
    labs(y = 'Inward Bias (°)', x = 'RT (s)', subtitle = sprintf('Exp 1 Subject #%s', si)) +
    th + theme(axis.text.x = element_text(angle = 45, hjust = 0.95), 
               legend.position = 'none') +
    scale_y_continuous(breaks = seq(-50, 100, 50)) + 
    coord_capped_cart(ylim = c(-50, 100)) 
  print(ind.plot) 
  
  ggsave(sprintf('E1_SUB%s_Grp%s_notitle_%s.pdf', si, groupvar, subDir), plot = ind.plot, height = 3, width = 4,  units = "in")
}
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'

Experiment 1 Group Data


E1.ind <- E1.data %>%
  filter(block >= 3 & fbi == 0 ) %>%
  group_by(SN, Distance, group) %>%
  dplyr::summarise(hand_mean = mean(Hand_IB, na.rm = TRUE), 
                   rt_mean = mean(RT, na.rm = TRUE))
`summarise()` has grouped output by 'SN', 'Distance'. You can override using the `.groups` argument.
E1.ind.base <- E1.data %>%
  filter(block< 3 & fbi == 0 ) %>%
  group_by(SN, Distance, group) %>%
  dplyr::summarise(hand_mean = mean(Hand_IB, na.rm = TRUE), 
                   rt_mean = mean(RT, na.rm = TRUE))
`summarise()` has grouped output by 'SN', 'Distance'. You can override using the `.groups` argument.
E1.grp <- E1.ind %>% 
  group_by(Distance, group) %>%
  dplyr::summarise(hand_grp_mean = mean(hand_mean, na.rm = TRUE),
                   hand_grp_stderr = std.error(hand_mean, na.rm = TRUE),
                   rt_grp_mean = mean(rt_mean, na.rm = TRUE), 
                   rt_grp_stderr = std.error(rt_mean, na.rm = TRUE))
`summarise()` has grouped output by 'Distance'. You can override using the `.groups` argument.
E1.grp.plot <- E1.ind %>%
  ggplot(aes(x = Distance, y = hand_mean, group = group)) + 
  geom_segment(aes(x=-5, xend=95, y = 0, yend = 0), color = 'lightgrey') +
  stat_summary(fun = 'mean', geom = "point") + 
  stat_summary(fun = 'mean', geom = "line", aes(linetype = factor(group))) + 
  stat_summary(fun.data = 'mean_se', geom = "errorbar", width = 2) + 
  labs(y = 'Inward Bias (°)', x = 'Probe Distance (°)') +
  scale_x_continuous(breaks = c(0, 30, 60, 90)) +
  th + theme(axis.text.x = element_text(angle = 45, hjust = 0.95), 
             legend.position = 'none') +
  coord_capped_cart(ylim = c(-5, 40))
print(E1.grp.plot)  

ggsave(sprintf('E1_Group_%s.pdf', subDir), plot = E1.grp.plot, height = 3, width = 4,  units = "in")

Experiment 1 Group Data, with First Peak (Obtained from MClust)


firstpeak <- setNames ( as.data.frame(matrix(nrow = 4, ncol = 5)), 
                        c("Distance", "group", "hand_mean", "hand_ub", "hand_lb") )

firstpeak$Distance <- c(0, 30, 60, 90)
firstpeak$hand_mean <- c(-1.1, 1.1, 4.2, 3.4)
firstpeak$hand_ub <- c(-1.1, 2.3, 5.1, 4.2)
firstpeak$hand_lb <- c(-1.1, 0.1, 3.2, 2.5)

E1.grpNoJit.plot <- E1.ind %>%
  filter(group == 1) %>%
  ggplot(aes(x = Distance, y = hand_mean, group = group)) + 
  geom_segment(aes(x=-5, xend=95, y = 0, yend = 0), color = 'lightgrey') +
  stat_summary(fun = 'mean', geom = "point") + 
  stat_summary(fun = 'mean', geom = "line", aes(linetype = factor(group))) + 
  stat_summary(fun.data = 'mean_se', geom = "errorbar", width = 2) + 
  geom_point(inherit.aes = FALSE, data = firstpeak, aes(x = Distance, y = hand_mean), color = "black")+
  geom_errorbar(inherit.aes = FALSE, data = firstpeak, aes(x = Distance, ymin = hand_lb, ymax = hand_ub), color = "black", width = 2)+
  geom_line(inherit.aes = FALSE, data = firstpeak, aes(x = Distance, y = hand_mean), color = "black", linetype = "dashed")+
  labs(y = 'Inward Bias (°)', x = 'Probe Distance (°)') +
  scale_x_continuous(breaks = c(0, 30, 60, 90)) +
  th + theme(axis.text.x = element_text(angle = 45, hjust = 0.95), 
             legend.position = 'none') +
  coord_capped_cart(ylim = c(-5, 40))
print(E1.grpNoJit.plot)  

ggsave(sprintf('E1_GroupNoJit_%s.pdf', subDir), plot = E1.grpNoJit.plot, height = 3, width = 4,  units = "in")


std.error(E1.ind$hand_mean[E1.ind$group == 1 & E1.ind$Distance == 0])
[1] 1.012352

Experiment 1 Quantile Analysis


E1.ind.Quantile.data <- E1.data %>%
  filter(block >= 3 & fbi == 0 ) %>%
  group_by(SN, Distance, group) %>%
  mutate(quantile = ntile(RT, 5)) %>%
  group_by(SN, Distance, quantile, group) %>%
  dplyr::summarise(bias_mean = mean(Hand_IB, na.rm = TRUE), 
                   RT_mean = mean(RT, na.rm = TRUE))
`summarise()` has grouped output by 'SN', 'Distance', 'quantile'. You can override using the `.groups` argument.
E1.Quantile.data <- E1.ind.Quantile.data %>% 
  group_by(Distance, quantile, group) %>%
  dplyr::summarise(bias_grp_mean = mean(bias_mean, na.rm = TRUE), 
                   bias_std_err = std.error(bias_mean, na.rm = TRUE), 
                   RT_grp_mean = mean(RT_mean, na.rm = TRUE), 
                   RT_std_err = std.error(RT_mean, na.rm = TRUE))
`summarise()` has grouped output by 'Distance', 'quantile'. You can override using the `.groups` argument.
E1.Quantile.grp1.plot <- E1.Quantile.data %>%
  filter(group == 1) %>%
  ggplot(aes(x = RT_grp_mean, y = bias_grp_mean, color = factor(Distance), group = factor(Distance))) + 
  geom_point() + 
  geom_line() + 
  geom_errorbarh(aes(xmax = RT_grp_mean + RT_std_err, xmin = RT_grp_mean - RT_std_err), alpha = 0.4)  +
  geom_errorbar(aes(ymax =bias_grp_mean + bias_std_err, ymin = bias_grp_mean - bias_std_err), alpha = 0.4) + 
  labs(y = 'Inward Bias (°)', x = 'RT (s)') +
  scale_color_manual(values = c('black', my.colors2[c(1, 2, 3)]), guide = FALSE) + 
  scale_x_continuous(breaks = seq(0.2, 0.6, 0.1)) + 
  theme(axis.text.x = element_text(angle = 45, hjust = 0.95), 
        legend.position = 'none') +
  th + 
  scale_y_continuous(breaks = c(0, 25, 50, 75)) +
  coord_capped_cart(ylim = c(-5, 75), xlim = c(0.175, 0.6)) 
print(E1.Quantile.grp1.plot)
Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please use `guide = "none"` instead.
ggsave(sprintf('E1_Quantile_Grp1_%s.pdf', subDir), plot = E1.Quantile.grp1.plot, height = 3, width = 4,  units = "in")
Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please use `guide = "none"` instead.

Experiment 1 Normalized Quintile Analysis


E1.ind.Quantile.norm.data <- E1.data %>%
  filter(block >= 3 & fbi == 0 & group == 1) %>%
  group_by(SN, Distance) %>%
  mutate(Scale_HandIB = scale(Hand_IB)) %>%
  mutate(quantile = ntile(RT, 5)) %>%
  group_by(SN, Distance, quantile) %>%
  dplyr::summarise(bias_mean = mean(Scale_HandIB, na.rm = TRUE), 
                   RT_mean = mean(RT, na.rm = TRUE))
`summarise()` has grouped output by 'SN', 'Distance'. You can override using the `.groups` argument.
E1.Quantile.norm.data <- E1.ind.Quantile.norm.data %>% 
  group_by(Distance, quantile) %>%
  dplyr::summarise(bias_grp_mean = mean(bias_mean, na.rm = TRUE), 
                   bias_std_err = std.error(bias_mean, na.rm = TRUE), 
                   RT_grp_mean = mean(RT_mean, na.rm = TRUE), 
                   RT_std_err = std.error(RT_mean, na.rm = TRUE))
`summarise()` has grouped output by 'Distance'. You can override using the `.groups` argument.
E1.Quantile.all.norm.plot <- E1.Quantile.norm.data %>%
  filter(Distance != 0) %>%
  ggplot(aes(x = RT_grp_mean, y = bias_grp_mean, color = factor(Distance), group = factor(Distance))) + 
  geom_point() + 
  geom_line() + 
  geom_errorbarh(aes(xmax = RT_grp_mean + RT_std_err, xmin = RT_grp_mean - RT_std_err), alpha = 0.4)  +
  geom_errorbar(aes(ymax =bias_grp_mean + bias_std_err, ymin = bias_grp_mean - bias_std_err), alpha = 0.4) + 
  labs(y = 'Inward Bias (norm)', x = 'RT (s)') +
  scale_color_manual(values = c(my.colors2[c(1, 2, 3)]), guide = FALSE) + 
  scale_x_continuous(breaks = seq(0.2, 0.7, 0.1)) + 
    th + 
  theme(axis.text.x = element_text(angle = 45, hjust = 0.95), 
        legend.position = 'none') 
print(E1.Quantile.all.norm.plot)

ggsave(sprintf('E1_Quantile_Grp1_Norm_%s.pdf', subDir), plot = E1.Quantile.all.norm.plot, height = 3, width = 4,  units = "in")

Trajectory

E1.traj.data <- as_tibble( read.csv("/Users/jonathantsay/Dropbox/MOTOR/use_dependent/UD_WithTraj.csv", header = TRUE, sep = ',')) %>%
  dplyr::select(SN:hx_138, hy_1:hy_138) 


for(si in unique(E1.traj.data$SN)){
  E1.traj.data.long <- E1.traj.data %>% 
    filter(SN == si) %>%
    gather(Cond, Value, hx_1:hy_138) %>%
    separate(Cond, into = c('XorY', 'Samplepoint', sep = "_")) %>%
    spread(XorY, Value)
  
  ind.traj.plot <- E1.traj.data.long %>%
    filter(block >= 3, fbi == 0) %>%
    drop_na(hx, hy) %>%  
    ggplot(aes(x = hx, y =hy, color = factor(ti), group = TN)) + 
    geom_path(size = 0.5) +
    coord_capped_cart(ylim = c(-150, 150), xlim = c(-150, 150)) +
    th +
    theme(axis.text.x = element_text(angle = 45, hjust = 0.95), 
          legend.position = 'none') +
    labs(x = 'x (mm)', y = 'y (mm)')
  
  print(ind.traj.plot)
  
  ggsave(sprintf('E1_SUB%s_Traj_%s.pdf', si, subDir), plot = ind.traj.plot, height = 3, width = 4,  units = "in")
  
}

Load in E2 (Reward exp) Hold time 500, with forced delay.


E2.data <- as_tibble( read.csv("/Users/jonathantsay/Dropbox/MOTOR/use_dependent/use-dependent-learning/UD_E2.csv", header = TRUE, sep = ',')) %>% 
  mutate(Distance_raw = as.double( abs(ti - trainTgt)), Distance = case_when(Distance_raw > 180 ~ abs(Distance_raw - 360),
                                                    Distance_raw < -180 ~ abs(Distance_raw + 360),
                                                    Distance_raw <= 180 & Distance_raw >= -180 ~ Distance_raw),
                                                    CN = TN,
                                                    Hand = hand_theta_40, Handb = NaN, RTb = NaN)


E2.data.base.out <- baseline_subtract(E2.data, 71, 140, 0)
E2.data <- E2.data.base.out[[1]]
E2.data.base <- E2.data.base.out[[2]]

# flip to inward bias 
E2.data <- E2.data %>%
  mutate(Hand_IB = case_when(trainTgt == 60 & (ti == 90   | ti == 120  | ti == 150 ) ~ -Handb, 
                             trainTgt == 60 & (ti == 0   | ti == 30  | ti == 330 | ti == 60) ~ Handb, 
                             trainTgt == 150 & (ti == 180  | ti == 210  | ti == 240) ~ -Handb, 
                             trainTgt == 150 & (ti == 60   | ti == 90  | ti == 120 | ti == 150) ~ Handb))

Experiment 2 Group Data


E2.ind <- E2.data %>%
  filter(block >= 3 & fbi == 0 ) %>%
  group_by(SN, Distance, group) %>%
  dplyr::summarise(hand_mean = mean(Hand_IB, na.rm = TRUE), 
                   rt_mean = mean(RT, na.rm = TRUE), 
                   mt_mean = mean(MT, na.rm = TRUE))
`summarise()` has grouped output by 'SN', 'Distance'. You can override using the `.groups` argument.
E2.grp <- E2.ind %>% 
  group_by(Distance, group) %>%
  dplyr::summarise(hand_grp_mean = mean(hand_mean, na.rm = TRUE),
                   hand_grp_stderr = std.error(hand_mean, na.rm = TRUE),
                   rt_grp_mean = mean(rt_mean, na.rm = TRUE), 
                   rt_grp_stderr = std.error(rt_mean, na.rm = TRUE))
`summarise()` has grouped output by 'Distance'. You can override using the `.groups` argument.
E2.grpBoth.plot <- E2.ind %>%
  ggplot(aes(x = Distance, y = hand_mean, group = group, color = group)) + 
  geom_segment(aes(x=-5, xend=95, y = 0, yend = 0), color = 'lightgrey') +
  stat_summary(fun = 'mean', geom = "point") + 
  stat_summary(fun = 'mean', geom = "line", linetype = 1) + 
  stat_summary(fun.data = 'mean_se', geom = "errorbar", width = 2) + 
  labs(y = 'Inward Bias (°)', x = 'Probe Distance (°)') +
  scale_x_continuous(breaks = c(0, 30, 60, 90)) +
  scale_color_manual(values = c( 'darkgrey', 'black')) +
  th + theme(axis.text.x = element_text(angle = 45, hjust = 0.95), 
             legend.position = 'none') +
  coord_capped_cart(ylim = c(-5, 10))
print(E2.grpBoth.plot)  

ggsave(sprintf('E2_GroupBoth_%s.pdf', subDir), plot = E2.grpBoth.plot, height = 3, width = 4,  units = "in")

Experiment 2: Quantile Analysis Combined


E2.data <- E2.data %>% mutate(SN_new = ifelse(group == "R", SN + 999, SN))

E2.Quantile.comb.data <-E2.data %>%
  filter(block >= 3 & fbi == 0 ) %>%
  group_by(SN_new, Distance) %>%
  mutate(quantile = ntile(RT, 5)) %>%
  group_by(SN_new, Distance, quantile) %>%
  dplyr::summarise(bias_mean = mean(Hand_IB, na.rm = TRUE), 
                   RT_mean = mean(RT, na.rm = TRUE)) %>%
  group_by(Distance, quantile) %>%
  dplyr::summarise(bias_grp_mean = mean(bias_mean, na.rm = TRUE), 
                   bias_std_err = std.error(bias_mean, na.rm = TRUE), 
                   RT_grp_mean = mean(RT_mean, na.rm = TRUE), 
                   RT_std_err = std.error(RT_mean, na.rm = TRUE))
`summarise()` has grouped output by 'SN_new', 'Distance'. You can override using the `.groups` argument.
`summarise()` has grouped output by 'Distance'. You can override using the `.groups` argument.
E2.Quantile.comb.plot <- E2.Quantile.comb.data %>%
  ggplot(aes(x = RT_grp_mean, y = bias_grp_mean, color = factor(Distance), group = factor(Distance))) + 
  geom_point() + 
  geom_line() + 
  geom_errorbarh(aes(xmax = RT_grp_mean + RT_std_err, xmin = RT_grp_mean - RT_std_err), alpha = 0.4)  +
  geom_errorbar(aes(ymax =bias_grp_mean + bias_std_err, ymin = bias_grp_mean - bias_std_err), alpha = 0.4) + 
  labs(y = 'Inward Bias (°)', x = 'RT (s)') +
  scale_color_manual(values = c('black', my.colors2[c(1, 2, 3)]), guide = FALSE) + 
  #scale_x_continuous(breaks = seq(0.2, 0.7, 0.1)) + 
  scale_y_continuous(breaks = seq(0, 10, 5)) + 
  theme(axis.text.x = element_text(angle = 45, hjust = 0.95), 
        legend.position = 'none') +
  th + 
  coord_capped_cart(ylim = c(-2, 10)) 
print(E2.Quantile.comb.plot)
Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please use `guide = "none"` instead.
ggsave(sprintf('E2_Quantile_Comb_%s.pdf', subDir), plot = E2.Quantile.comb.plot, height = 3, width = 4,  units = "in")
Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please use `guide = "none"` instead.


for(si in unique(E2.data$SN)){
  
  pro.data <- E2.data %>% 
    filter(SN == si) %>%  
    filter(block >= 3 & fbi == 0 & Distance > 0 & RT < 3)
  
  groupvar <- 1
  myymin <- min( pro.data$RT[pro.data$SN == si & pro.data$block >= 3 & pro.data$fbi == 0], na.rm = TRUE) + 0.2
  myymax <- max( pro.data$RT[pro.data$SN == si & pro.data$block >= 3 & pro.data$fbi == 0], na.rm = TRUE) - 0.2
  
  ind.plot <- pro.data %>%
    ggplot(aes(x = RT, y = Hand_IB, group = factor(Distance))) + 
    geom_point(alpha = 0.4, aes(color = factor(Distance))) + 
    geom_smooth(method = 'lm', aes(color = factor(Distance)), size = 0.5, se = FALSE, linetype= groupvar) + 
    facet_rep_wrap(.~Distance, repeat.tick.labels = TRUE, ncol = 4) + 
    #scale_x_continuous(breaks = c(round(myymin, 1), round(myymax, 1) )) +
    scale_color_manual(values = c(my.colors2[c(1, 2, 3)]), guide = FALSE) + 
    labs(y = 'Inward Bias (°)', x = 'RT (s)', subtitle = sprintf('Exp 2 Subject #%s', si)) + 
    th + theme(axis.text.x = element_text(angle = 45, hjust = 0.95), 
               legend.position = 'none') +
    coord_capped_cart(ylim = c(-25, 25)) 
  print(ind.plot) 
  
  ggsave(sprintf('aE2_SUB%s_Grp%s_%s.pdf', si, groupvar, subDir), plot = ind.plot, height = 3, width = 4,  units = "in")
  
}
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'
`geom_smooth()` using formula 'y ~ x'


rewardcdf <- E2.data %>%
  filter(block >= 3 & Distance == 0) %>%
  ggplot(aes(x = abs(hand_theta), alpha = group)) + 
  stat_ecdf(geom = "step") + 
  scale_alpha_manual(values = c(0.2, 1), guide = FALSE) +
  scale_x_continuous(limits = c(0, 40)) +
  labs(y = 'Cumulative Probability', x = 'Error (°)') +
  th
print(rewardcdf)
Warning: Removed 13 rows containing non-finite values (stat_ecdf).
Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please use `guide = "none"` instead.
ggsave(sprintf('E2_rewardcdf_%s.pdf', subDir), plot = rewardcdf, height = 3, width = 3,  units = "in")
Warning: Removed 13 rows containing non-finite values (stat_ecdf).
Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please use `guide = "none"` instead.

E1 Bimodal


E1.data$Distance <- factor(E1.data$Distance, levels = c("0", "30", "60", "90"))
E1.data.density <- E1.data %>%
  filter(block > 2) %>%
  ggplot(aes(x = Hand_IB, fill = Distance)) +
  geom_density(alpha = 0.5) +
  scale_x_continuous(breaks = seq(-30, 120, 30)) +
  facet_rep_wrap(Distance~., ncol = 4, repeat.tick.labels = TRUE) + 
  th + theme(legend.position = "none") + 
  scale_fill_manual(values = c('black', my.colors2[c(1, 2, 3)]), guide = FALSE) +
  coord_capped_cart(xlim = c(-30, 120)) +
  labs(x = "Heading Angle (°)", y = "Probability Density")
print(E1.data.density)

#setwd("~/Desktop")
ggsave(sprintf('E1_Density_%s.pdf', subDir), plot = E1.data.density, height = 3, width = 10.5,  units = "in")


VS.data.allprobes <-  as_tibble( read.csv("/Users/jonathantsay/Dropbox/MOTOR/use_dependent/use-dependent-learning/VerstynenSabes2011.csv", header = TRUE, sep = ',')) %>% mutate(Bias = Hand_IB)

VS.data.density <- VS.data.allprobes %>%
  ggplot(aes(x = Hand_IB, fill = factor(Distance)))  +
  geom_density(alpha = 0.5) +
   scale_x_continuous(breaks = seq(-30, 120, 30), limits = c(-60, 150)) +
  facet_rep_wrap(Distance~., ncol = 4, repeat.tick.labels = TRUE) + 
  th + theme(legend.position = "none") + 
  scale_fill_manual(values = c('black', my.colors2[c(1, 2, 3)]), guide = FALSE) +
  labs(x = "Heading Angle (°)", y = "Probability Density")
print(VS.data.density)
Warning: Removed 1 rows containing non-finite values (stat_density).

setwd("~/Desktop")
Warning: The working directory was changed to /Users/jonathantsay/Desktop inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
#ggsave(sprintf('VS_Density_%s.pdf', subDir), plot = VS.data.density, height = 3, width = 10.5,  units = "in")

E2 Bimodal


E2.data$Distance <- factor(E2.data$Distance, levels = c("0", "30", "60", "90"))
E2.data.density <- E2.data %>%
  filter(block > 2) %>%
  ggplot(aes(x = Hand_IB, fill = Distance)) +
  #geom_histogram(binwidth = 5) +
  geom_density(alpha = 0.5) +
  #geom_vline(xintercept = 90, linetype = "dotted") +
  scale_x_continuous(breaks = seq(-30, 120, 30), limits = c(-60, 150)) +
  coord_capped_cart(xlim = c(-30,120)) +
  facet_rep_wrap(Distance~., ncol = 4, repeat.tick.labels = TRUE) + 
  th + theme(legend.position = "none") + 
  scale_fill_manual(values = c('black', my.colors2[c(1, 2, 3)]), guide = FALSE) +
  labs(x = "Heading Angle (°)", y = "Probability Density")
print(E2.data.density)
Warning: Removed 10 rows containing non-finite values (stat_density).
#setwd("~/Desktop")
ggsave(sprintf('E2_Density_%s.pdf', subDir), plot = E2.data.density, height = 3, width = 10.5,  units = "in")
Warning: Removed 10 rows containing non-finite values (stat_density).

E1 modeling


E1.data$Distance <- factor(E1.data$Distance, levels = c(0, 90, 30, 60))
E1.data.mod <- E1.data %>% filter(group == 1 & block >= 3) %>% group_by(SN, Distance) %>% mutate(scale_Hand_IB = scale(Hand_IB))
myE1mod <- lmer(scale_Hand_IB ~ RT * factor(Distance) + (1 |SN), data = E1.data.mod %>% filter(Distance != "0"))
boundary (singular) fit: see ?isSingular
Warning: Model failed to converge with 1 negative eigenvalue: -1.5e+04
summary(myE1mod)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: scale_Hand_IB ~ RT * factor(Distance) + (1 | SN)
   Data: E1.data.mod %>% filter(Distance != "0")

REML criterion at convergence: 2581.6

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-2.7395 -0.6803 -0.0354  0.6034  3.7991 

Random effects:
 Groups   Name        Variance  Std.Dev. 
 SN       (Intercept) 4.527e-34 2.128e-17
 Residual             8.550e-01 9.247e-01
Number of obs: 960, groups:  SN, 10

Fixed effects:
                        Estimate Std. Error         df t value Pr(>|t|)    
(Intercept)             0.675877   0.115995 954.000000   5.827 7.72e-09 ***
RT                     -1.808606   0.277871 954.000000  -6.509 1.22e-10 ***
factor(Distance)30      0.177712   0.170048 954.000000   1.045   0.2963    
factor(Distance)60     -0.007582   0.170643 954.000000  -0.044   0.9646    
RT:factor(Distance)30  -0.854560   0.449122 954.000000  -1.903   0.0574 .  
RT:factor(Distance)60  -0.123912   0.431110 954.000000  -0.287   0.7738    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
            (Intr) RT     f(D)30 f(D)60 RT:(D)3
RT          -0.895                             
fctr(Dst)30 -0.682  0.611                      
fctr(Dst)60 -0.680  0.609  0.464               
RT:fct(D)30  0.554 -0.619 -0.900 -0.376        
RT:fct(D)60  0.577 -0.645 -0.394 -0.903  0.399 
convergence code: 0
boundary (singular) fit: see ?isSingular
Anova(myE1mod, type = 'III')
Analysis of Deviance Table (Type III Wald chisquare tests)

Response: scale_Hand_IB
                      Chisq Df Pr(>Chisq)    
(Intercept)         33.9515  1  5.650e-09 ***
RT                  42.3644  1  7.576e-11 ***
factor(Distance)     1.4487  2     0.4846    
RT:factor(Distance)  3.8846  2     0.1434    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
eta_sq(myE1mod)
Warning: Model failed to converge with 1 negative eigenvalue: -1.5e+04
Warning: Currently only supports partial eta squared for this class of objects.
                 term etasq
1                  RT 0.122
2    factor(Distance) 0.002
3 RT:factor(Distance) 0.004

VS modeling


VS.data$Distance <- factor(VS.data$Distance, levels = c(0, 30, 60, 90))
VS.data <- VS.data %>% group_by(SN, Distance) %>% mutate(scale_hand_IB = scale(Hand_IB))
myVSmod <- lmer(Hand_IB ~  RT * factor(Distance) + (1|SN), data = VS.data)
summary(myVSmod)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: Hand_IB ~ RT * factor(Distance) + (1 | SN)
   Data: VS.data

REML criterion at convergence: 5506.1

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-3.6100 -0.5525 -0.0734  0.4984  4.1101 

Random effects:
 Groups   Name        Variance Std.Dev.
 SN       (Intercept)  43.62    6.604  
 Residual             223.44   14.948  
Number of obs: 671, groups:  SN, 8

Fixed effects:
                      Estimate Std. Error       df t value Pr(>|t|)    
(Intercept)              4.054      7.746  335.767   0.523  0.60108    
RT                     -12.227     22.841  660.334  -0.535  0.59261    
factor(Distance)30      29.856      9.208  657.002   3.242  0.00125 ** 
factor(Distance)60      57.332      8.866  656.755   6.466 1.96e-10 ***
factor(Distance)90      97.954      8.775  656.919  11.163  < 2e-16 ***
RT:factor(Distance)30  -67.471     28.245  656.910  -2.389  0.01719 *  
RT:factor(Distance)60 -137.197     26.567  656.749  -5.164 3.21e-07 ***
RT:factor(Distance)90 -232.285     26.214  656.894  -8.861  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
            (Intr) RT     f(D)30 f(D)60 f(D)90 RT:(D)3 RT:(D)6
RT          -0.933                                            
fctr(Dst)30 -0.639  0.650                                     
fctr(Dst)60 -0.687  0.701  0.581                              
fctr(Dst)90 -0.694  0.707  0.586  0.615                       
RT:fct(D)30  0.627 -0.672 -0.979 -0.569 -0.575                
RT:fct(D)60  0.698 -0.748 -0.581 -0.976 -0.617  0.598         
RT:fct(D)90  0.708 -0.759 -0.588 -0.618 -0.976  0.606   0.652 
Anova(myVSmod, type = 'III')
Analysis of Deviance Table (Type III Wald chisquare tests)

Response: Hand_IB
                       Chisq Df Pr(>Chisq)    
(Intercept)           0.2739  1     0.6007    
RT                    0.2866  1     0.5924    
factor(Distance)    142.1544  3     <2e-16 ***
RT:factor(Distance)  92.7832  3     <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
eta_sq(myVSmod)
Warning: Currently only supports partial eta squared for this class of objects.
                 term etasq
1                  RT 0.150
2    factor(Distance) 0.178
3 RT:factor(Distance) 0.124

E2 modeling


E2.data$Distance <- factor(E2.data$Distance, levels = c(0, 30, 60, 90))
myE2mod <- lmer(Hand_IB ~ RT*Distance + (SN_new| group), data = E2.data %>% filter(block >= 3 & fbi == 0 ))
boundary (singular) fit: see ?isSingular
summary(myE2mod)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: Hand_IB ~ RT * Distance + (SN_new | group)
   Data: E2.data %>% filter(block >= 3 & fbi == 0)

REML criterion at convergence: 178363.2

Scaled residuals: 
     Min       1Q   Median       3Q      Max 
-20.8926  -0.5479   0.0148   0.5748  19.9080 

Random effects:
 Groups   Name        Variance  Std.Dev. Corr 
 group    (Intercept) 1.316e+02 11.4730       
          SN_new      8.761e-03  0.0936  -1.00
 Residual             8.304e+01  9.1129       
Number of obs: 24576, groups:  group, 2

Fixed effects:
                Estimate Std. Error         df t value Pr(>|t|)    
(Intercept)      24.8318     1.5932     7.3262  15.586 6.96e-07 ***
RT                3.8310     0.2148 24523.8910  17.836  < 2e-16 ***
Distance30        2.4831     1.2907 24560.4302   1.924   0.0544 .  
Distance60        6.3609     1.5142 24560.9518   4.201 2.67e-05 ***
Distance90        7.7762     1.0511 24559.8088   7.398 1.42e-13 ***
RT:Distance30     0.6921     1.3796 24560.4580   0.502   0.6159    
RT:Distance60    -2.8172     1.6541 24561.0021  -1.703   0.0886 .  
RT:Distance90    -5.4704     1.1124 24559.7931  -4.918 8.82e-07 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
            (Intr) RT     Dstn30 Dstn60 Dstn90 RT:D30 RT:D60
RT          -0.183                                          
Distance30  -0.007  0.152                                   
Distance60  -0.002  0.129  0.022                            
Distance90  -0.020  0.187  0.032  0.027                     
RT:Distnc30  0.005 -0.154 -0.977 -0.021 -0.029              
RT:Distnc60  0.000 -0.128 -0.020 -0.983 -0.024  0.020       
RT:Distnc90  0.018 -0.192 -0.030 -0.025 -0.965  0.030  0.025
convergence code: 0
boundary (singular) fit: see ?isSingular
Anova(myE2mod, type = 'III')
Analysis of Deviance Table (Type III Wald chisquare tests)

Response: Hand_IB
              Chisq Df Pr(>Chisq)    
(Intercept) 242.913  1  < 2.2e-16 ***
RT          318.134  1  < 2.2e-16 ***
Distance     73.326  3  8.275e-16 ***
RT:Distance  27.143  3  5.494e-06 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
eta_sq(myE2mod)
Warning: Currently only supports partial eta squared for this class of objects.
         term etasq
1          RT 0.000
2    Distance 0.003
3 RT:Distance 0.001

Make overlapping distribution


E1.data$Distance <- factor(E1.data$Distance, levels = c("0", "30", "60", "90"))
E1.data.density.sub <- E1.data %>%
  filter(block > 2) %>%
  ggplot(aes(x = Hand_IB, fill = Distance, group = factor(SN))) +
  #geom_histogram(binwidth = 5) +
  #geom_vline(xintercept = 90, linetype = "dotted") +
  geom_density(alpha = 0.1, size = 0.1) +
  scale_x_continuous(breaks = seq(-30, 120, 30)) +
  facet_rep_wrap(Distance~., ncol = 4, repeat.tick.labels = TRUE) + 
  th + theme(legend.position = "none") + 
  scale_fill_manual(values = c('black', my.colors2[c(1, 2, 3)]), guide = FALSE) +
  coord_capped_cart(xlim = c(-30, 120)) +
  labs(x = "Heading Angle (°)", y = "Probability Density")
print(E1.data.density.sub)

ggsave(sprintf('E1_ind_density_%s.pdf', subDir), plot = E1.data.density.sub, height = 3, width = 10.5,  units = "in")


E2.data$Distance <- factor(E2.data$Distance, levels = c("0", "30", "60", "90"))
E2.data.density.sub <- E2.data %>%
  filter(block > 2) %>%
  ggplot(aes(x = Hand_IB, fill = Distance, group = factor(SN))) +
  #geom_histogram(binwidth = 5) +
  geom_density(alpha = 0.1, size = 0.1) +
  #geom_vline(xintercept = 90, linetype = "dotted") +
  scale_x_continuous(breaks = seq(-30, 120, 30), limits = c(-60, 150)) +
  coord_capped_cart(xlim = c(-30,120)) +
  facet_rep_wrap(Distance~., ncol = 4, repeat.tick.labels = TRUE) + 
  th + theme(legend.position = "none") + 
  scale_fill_manual(values = c('black', my.colors2[c(1, 2, 3)]), guide = FALSE) +
  labs(x = "Heading Angle (°)", y = "Probability Density")
print(E2.data.density.sub)
Warning: Removed 10 rows containing non-finite values (stat_density).
ggsave(sprintf('E2_ind_density_%s.pdf', subDir), plot = E2.data.density.sub, height = 3, width = 10.5,  units = "in")
Warning: Removed 10 rows containing non-finite values (stat_density).

LS0tCnRpdGxlOiAiVXNlIGRlcGVuZGVudCBwYXBlciIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKCmBgYHtyLCBtZXNzYWdlID0gRkFMU0V9CgoKcm0obGlzdCA9IGxzKCkpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KCdzdmdsaXRlJykKbGlicmFyeShicm9vbSkKbGlicmFyeShwdXJycikKbGlicmFyeShsZW1vbikKbGlicmFyeShwcmFjbWEpCmxpYnJhcnkobHVicmlkYXRlKQpsaWJyYXJ5KHBsb3RyaXgpCmxpYnJhcnkobG1lNCkKbGlicmFyeShsbWVyVGVzdCkKbGlicmFyeShjYXIpCmxpYnJhcnkoc2pzdGF0cykKCmNhbGxfYWVzdGhldGhpY3MgPC0gZnVuY3Rpb24odGV4dF9zaXplKXsKICAKICB0aCA8LSB0aGVtZSggICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgICAgICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgICAgICAgICAgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgICAgICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgICAgICAgICAgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKHNpemUgPSAwLjUpLCAKICAgICAgICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAncmlnaHQnLCAKICAgICAgICAgICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPSB0ZXh0X3NpemUsIGZhbWlseT0iSGVsdmV0aWNhIiksCiAgICAgICAgICAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPSB0ZXh0X3NpemUsIGZhbWlseT0iSGVsdmV0aWNhIiksIAogICAgICAgICAgICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gcmVsKDAuOTApKSwgCiAgICAgICAgICAgICAgICAgc3RyaXAudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSByZWwoMC45MCkpLCAKICAgICAgICAgICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQodmp1c3Q9LTAuMyksIAogICAgICAgICAgICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIHZqdXN0ID0gMCksIAogICAgICAgICAgICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2xpbmUoc2l6ZSA9IDAuNCksIAogICAgICAgICAgICAgICAgIGF4aXMudGV4dC54LmJvdHRvbSAgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHJlbCgwLjkwKSwgbWFyZ2luID0gdW5pdChjKHQgPSAyLjUsIHIgPSAwLCBiID0gMCwgbCA9IDApLCAibW0iKSksCiAgICAgICAgICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHZqdXN0ID0gMSksCiAgICAgICAgICAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHJlbCgwLjkwKSwgbWFyZ2luID0gdW5pdChjKHQgPSAwLCByID0gMi41LCBiID0gMCwgbCA9IDApLCAibW0iKSksCiAgICAgICAgICAgICAgICAgYXhpcy50aWNrcy5sZW5ndGggPSB1bml0KC0xLjIsICJtbSIpLAogICAgICAgICAgICAgICAgIGF4aXMudGV4dC54LnRvcCA9IGVsZW1lbnRfdGV4dChzaXplID0gcmVsKDAuOTApLCBtYXJnaW4gPSB1bml0KGModCA9IDAsIHIgPSAwLCBiID0gMi41LCBsID0gMCksICJtbSIpKSkKICAKICByZXR1cm4odGgpCn0KCm15LmNvbG9yczIgPC0gIGMoIiMwMDY2MDAiLCAiIzgwMDA4MCIsICIjRkY5OTAwIiwgJ2RlZXBza3libHVlNCcpCnRoIDwtIGNhbGxfYWVzdGhldGhpY3MoMTYpCgojIGJhc2VsaW5lIHN1YnRyYWN0aW9uIGZ1bmN0aW9uCmJhc2VsaW5lX3N1YnRyYWN0IDwtIGZ1bmN0aW9uKG15LmRhdGEsIGJhc2VfY25fc3RhcnQsIGJhc2VfY25fZW5kLCByZXR1cm5BbmdsZSl7CiAgCiAgCiAgbXkuc3ViamVjdHMgPC0gdW5pcXVlKG15LmRhdGEkU04pCiAgY291bnRlciA8LSAxCiAgbXliYXNlbGluZSA8LSBzZXROYW1lcyAoIGRhdGEuZnJhbWUobWF0cml4KE5hTiwgbnJvdyA9IGxlbmd0aChteS5zdWJqZWN0cykgKiAxMiwgbmNvbCA9IDUpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoJ1NOJywgJ3RpJywgJ0hhbmRfYmFzZScsICdSVF9iYXNlJywnUmV0dXJuX2Jhc2UnKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogIGZvcihzaSBpbiBteS5zdWJqZWN0cyl7CiAgICAKICAgIGlkeCA8LSBteS5kYXRhJFNOID09IHNpCiAgICAgIAogICAgZm9yKG1pIGluIHVuaXF1ZShteS5kYXRhJHRpW2lkeF0pKXsKICAgICAgCiAgICAgIGlkeF9zdWIgPC0gbXkuZGF0YSRTTiA9PSBzaSAmIG15LmRhdGEkdGkgPT0gbWkKICAgICAgaWR4X2JsIDwtIG15LmRhdGEkU04gPT0gc2kgJiBteS5kYXRhJHRpID09IG1pICYgCiAgICAgICAgbXkuZGF0YSRDTiA+PSBiYXNlX2NuX3N0YXJ0ICYgbXkuZGF0YSRDTiA8PSBiYXNlX2NuX2VuZAogICAgICAKICAgICAgc3ViX0hhbmRfbWVhbiA8LSBtZWFuKG15LmRhdGEkSGFuZFtpZHhfYmxdLCBuYS5ybSA9IFRSVUUpCiAgICAgIG15LmRhdGEkSGFuZGJbaWR4X3N1Yl0gPC0gbXkuZGF0YSRIYW5kW2lkeF9zdWJdIC0gc3ViX0hhbmRfbWVhbgogICAgICAKICAgICAgc3ViX1JUX21lYW4gPC0gbWVhbihteS5kYXRhJFJUW2lkeF9ibF0sIG5hLnJtID0gVFJVRSkKICAgICAgbXkuZGF0YSRSVGJbaWR4X3N1Yl0gPC0gbXkuZGF0YSRSVFtpZHhfc3ViXSAtIHN1Yl9SVF9tZWFuCiAgICAgIAogICAgICBpZihyZXR1cm5BbmdsZSA9PSAxKXsKICAgICAgICBzdWJfUmV0dXJuX21lYW4gPC0gbWVhbihteS5kYXRhJFJldHVybkFuZ2xlW2lkeF9ibF0sIG5hLnJtID0gVFJVRSkKICAgICAgICBteS5kYXRhJFJldHVybkFuZ2xlYltpZHhfc3ViXSA8LSBteS5kYXRhJFJldHVybkFuZ2xlW2lkeF9zdWJdIC0gc3ViX1JldHVybl9tZWFuCiAgICAgICAgbXliYXNlbGluZSRSZXR1cm5fYmFzZVtjb3VudGVyXSA8LSBzdWJfUmV0dXJuX21lYW4KICAgICAgfQogICAgICAKICAgICAgbXliYXNlbGluZSRTTltjb3VudGVyXSA8LSBzaQogICAgICBteWJhc2VsaW5lJHRpW2NvdW50ZXJdIDwtIG1pCiAgICAgIG15YmFzZWxpbmUkSGFuZF9iYXNlW2NvdW50ZXJdIDwtIHN1Yl9IYW5kX21lYW4KICAgICAgbXliYXNlbGluZSRSVF9iYXNlW2NvdW50ZXJdIDwtIHN1Yl9SVF9tZWFuCiAgICAgIGNvdW50ZXIgPC0gY291bnRlciArIDEKICAgIH0KICB9CiAgCiAgcmV0dXJuKGxpc3QobXkuZGF0YSwgbXliYXNlbGluZSkpCn0KCgoKYGBgCgpgYGB7ciBzZXR1cH0KCgptYWluRGlyIDwtICJ+L0Ryb3Bib3gvVklDRS9KVC9LSU1fVVNFREVQRU5ERU5UL0ZpZ3VyZXMiCnN1YkRpciA8LSB0b2RheSgpCmZpZ0RpciA8LSAifi9Ecm9wYm94L1ZJQ0UvSlQvS0lNX1VTRURFUEVOREVOVC9GaWd1cmVzLyIKa25pdHI6Om9wdHNfa25pdCRzZXQocm9vdC5kaXIgPSBmaWdEaXIpCmRpci5jcmVhdGUoZmlsZS5wYXRoKG1haW5EaXIsIHN1YkRpciksIHNob3dXYXJuaW5ncyA9IEZBTFNFKQoKCmBgYAoKClJlbmFsYXlzaXMgb2YgViZTCmBgYHtyfQoKVlMuZGF0YSA8LSBhc190aWJibGUoIHJlYWQuY3N2KCIvVXNlcnMvam9uYXRoYW50c2F5L0Ryb3Bib3gvTU9UT1IvdXNlX2RlcGVuZGVudC91c2UtZGVwZW5kZW50LWxlYXJuaW5nL1ZlcnN0eW5lblNhYmVzMjAxMS5jc3YiLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAnLCcpKSAlPiUgbXV0YXRlKEJpYXMgPSBIYW5kX0lCKQoKYGBgCgpWUyBJbmRpdmlkdWFsIGRhdGEgCmBgYHtyfQoKCmZvcihzaSBpbiB1bmlxdWUoVlMuZGF0YSRTTikpewogIAogIGluZC5wbG90IDwtIFZTLmRhdGEgJT4lIAogICAgZmlsdGVyKFNOID09IHNpICYgRGlzdGFuY2UgPiAwKSAlPiUgIAogICAgZ2dwbG90KGFlcyh4ID0gUlQsIHkgPSBCaWFzLCBncm91cCA9IGZhY3RvcihEaXN0YW5jZSkpKSArIAogICAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNCwgYWVzKGNvbG9yID0gZmFjdG9yKERpc3RhbmNlKSkpICsgCiAgICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBhZXMoY29sb3IgPSBmYWN0b3IoRGlzdGFuY2UpKSwgc2l6ZSA9IDAuNSwgc2UgPSBGQUxTRSkgKyAKICAgICNzdGF0X2NvcihtZXRob2QgPSAncGVhcnNvbicpKyAKICAgIGZhY2V0X3JlcF93cmFwKC5+RGlzdGFuY2UsIHJlcGVhdC50aWNrLmxhYmVscyA9IFRSVUUpICsgCiAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gbXkuY29sb3JzMltjKDEsIDIsIDMpXSwgZ3VpZGUgPSBGQUxTRSkgKyAKICAgIGxhYnMoeSA9ICdJbndhcmQgQmlhcyAowrApJywgeCA9ICdSVCAocyknKSArICNzdWJ0aXRsZSA9IHNwcmludGYoJ1YmUyBTdWJqZWN0ICMlcycsIHNpKSAKICAgIHRoICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAwLjk1KSwgCiAgICAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJykgKwogICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGMoMC4yLCAwLjQpKSArIAogICAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgtNTAsIDEwMCwgNTApKSArIAogICAgY29vcmRfY2FwcGVkX2NhcnQoeWxpbSA9IGMoLTUwLCAxMDApKSAKICBwcmludChpbmQucGxvdCkgCiAgCiAgZ2dzYXZlKHNwcmludGYoJ1ZTX1NVQiVzX25vdGl0bGVfJXMucGRmJywgc2ksc3ViRGlyKSwgcGxvdCA9IGluZC5wbG90LCBoZWlnaHQgPSAzLCB3aWR0aCA9IDYsICB1bml0cyA9ICJpbiIpCiAgCn0KCgoKYGBgCgoKClZTLmdyb3VwIGRhdGEKYGBge3J9CgpWUy5kYXRhLmluZCA8LSBWUy5kYXRhICU+JQogIGdyb3VwX2J5KFNOLCBEaXN0YW5jZSkgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShiaWFzX21lYW4gPSBtZWFuKEJpYXMsIG5hLnJtID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgcnRfbWVhbiA9IG1lYW4oUlQsIG5hLnJtID0gVFJVRSkpCgpWUy5kYXRhLmdycCA8LSBWUy5kYXRhLmluZCAlPiUKICBncm91cF9ieShEaXN0YW5jZSkgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShiaWFzX2dycF9tZWFuID0gbWVhbihiaWFzX21lYW4sIG5hLnJtID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgYmlhc19zdGRlcnJfbWVhbiA9IHN0ZC5lcnJvcihiaWFzX21lYW4sIG5hLnJtID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgcnRfZ3JwX21lYW4gPSBtZWFuKHJ0X21lYW4sIG5hLnJtID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgcnRfc3RkZXJyX21lYW4gPSBzdGQuZXJyb3IocnRfbWVhbiwgbmEucm0gPSBUUlVFKSkgJT4lCiAgYWRkX3JvdyhEaXN0YW5jZSA9IDAsICBiaWFzX2dycF9tZWFuPSAwLCBiaWFzX3N0ZGVycl9tZWFuID0gMCkKClZTLmdycCA8LSBWUy5kYXRhLmdycCAlPiUKICBtdXRhdGUoZ3JvdXB2YXIgPSAxKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBEaXN0YW5jZSwgeSA9IGJpYXNfZ3JwX21lYW4sIGdyb3VwID0gZ3JvdXB2YXIpKSArIAogIGdlb21fc2VnbWVudChhZXMoeD0tNSwgeGVuZD05NSwgeSA9IDAsIHllbmQgPSAwKSwgY29sb3IgPSAnbGlnaHRncmV5JykgKwogIGdlb21fcG9pbnQoKSArIAogIGdlb21fbGluZSgpICsgCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IGJpYXNfZ3JwX21lYW4gLSBiaWFzX3N0ZGVycl9tZWFuLCB5bWF4ID0gYmlhc19ncnBfbWVhbiArIGJpYXNfc3RkZXJyX21lYW4pLCB3aWR0aCA9IDAuMikgKyAKICBsYWJzKHkgPSAnSW53YXJkIEJpYXMgKMKwKScsIHggPSAnUHJvYmUgRGlzdGFuY2UgKMKwKScpICsKICB0aCArIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMC45NSksIAogICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gJ25vbmUnKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCAyNSwgNSkpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGMoMCwgMzAsIDYwLCA5MCkpICsgCiAgY29vcmRfY2FwcGVkX2NhcnQoeWxpbSA9IGMoLTUsIDI1KSkKcHJpbnQoVlMuZ3JwKQoKZ2dzYXZlKHNwcmludGYoJ1ZTX0dyb3VwXyVzLnBkZicsIHN1YkRpciksIHBsb3QgPSBWUy5ncnAsIGhlaWdodCA9IDMsIHdpZHRoID0gNCwgIHVuaXRzID0gImluIikKCmBgYAoKVlMgUXVhbnRpbGUgQW5hbHlzaXMKYGBge3J9CgpWUy5RdWFudGlsZS5wbG90IDwtIFZTLmRhdGEgJT4lCiAgZ3JvdXBfYnkoU04sIERpc3RhbmNlKSAlPiUKICBtdXRhdGUocXVhbnRpbGUgPSBudGlsZShSVCwgNSkpICU+JQogIGdyb3VwX2J5KFNOLCBEaXN0YW5jZSwgcXVhbnRpbGUpICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoYmlhc19tZWFuID0gbWVhbihCaWFzLCBuYS5ybSA9IFRSVUUpLCAKICAgICAgICAgICAgICAgICAgIFJUX21lYW4gPSBtZWFuKFJULCBuYS5ybSA9IFRSVUUpKSAlPiUKICBncm91cF9ieShEaXN0YW5jZSwgcXVhbnRpbGUpICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoYmlhc19ncnBfbWVhbiA9IG1lYW4oYmlhc19tZWFuLCBuYS5ybSA9IFRSVUUpLCAKICAgICAgICAgICAgICAgICAgIGJpYXNfc3RkX2VyciA9IHN0ZC5lcnJvcihiaWFzX21lYW4sIG5hLnJtID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgUlRfZ3JwX21lYW4gPSBtZWFuKFJUX21lYW4sIG5hLnJtID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgUlRfc3RkX2VyciA9IHN0ZC5lcnJvcihSVF9tZWFuLCBuYS5ybSA9IFRSVUUpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBSVF9ncnBfbWVhbiwgeSA9IGJpYXNfZ3JwX21lYW4sIGNvbG9yID0gZmFjdG9yKERpc3RhbmNlKSxncm91cCA9IGZhY3RvcihEaXN0YW5jZSkpKSArIAogIGdlb21fcG9pbnQoKSArIAogIGdlb21fbGluZSgpICsgCiAgZ2VvbV9lcnJvcmJhcmgoYWVzKHhtYXggPSBSVF9ncnBfbWVhbiArIFJUX3N0ZF9lcnIsIHhtaW4gPSBSVF9ncnBfbWVhbiAtIFJUX3N0ZF9lcnIpLCBhbHBoYSA9IDAuNCkgICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWF4ID1iaWFzX2dycF9tZWFuICsgYmlhc19zdGRfZXJyLCB5bWluID0gYmlhc19ncnBfbWVhbiAtIGJpYXNfc3RkX2VyciksIGFscGhhID0gMC40KSArIAogIGxhYnMoeSA9ICdJbndhcmQgQmlhcyAowrApJywgeCA9ICdSVCAocyknKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoImJsYWNrIiwgbXkuY29sb3JzMltjKDEsIDIsIDMpXSksIGd1aWRlID0gRkFMU0UpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLjEsIDAuNSwgMC4xKSkgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDAuOTUpLCAKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAnbm9uZScpICsKICB0aCArIAogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKDAsIDIwLCA0MCkpICsKICBjb29yZF9jYXBwZWRfY2FydCh5bGltID0gYygtNSwgNDApLHhsaW0gPSBjKDAuMiwgMC41KSkgCnByaW50KFZTLlF1YW50aWxlLnBsb3QpCgpnZ3NhdmUoc3ByaW50ZignVlNfUXVhbnRpbGVfJXMucGRmJywgc3ViRGlyKSwgcGxvdCA9IFZTLlF1YW50aWxlLnBsb3QsIGhlaWdodCA9IDMsIHdpZHRoID0gNCwgIHVuaXRzID0gImluIikKCmBgYAoKCgoKVlMgUXVpbnRpbGUgTm9ybWFsaXplIFJULUJpYXMgRGVwZW5kZW5jeQpgYGB7cn0KClZTLlF1YW50aWxlLm5vcm0ucGxvdCA8LSBWUy5kYXRhICU+JQogIGdyb3VwX2J5KFNOLCBEaXN0YW5jZSkgJT4lCiAgZmlsdGVyKERpc3RhbmNlICE9IDApICU+JQogIG11dGF0ZShTY2FsZV9IYW5kSUIgPSBzY2FsZShIYW5kX0lCKSkgJT4lCiAgbXV0YXRlKHF1YW50aWxlID0gbnRpbGUoUlQsIDUpKSAlPiUKICBncm91cF9ieShTTiwgRGlzdGFuY2UsIHF1YW50aWxlKSAlPiUKICBkcGx5cjo6c3VtbWFyaXNlKGJpYXNfbWVhbiA9IG1lYW4oU2NhbGVfSGFuZElCLCBuYS5ybSA9IFRSVUUpLCAKICAgICAgICAgICAgICAgICAgIFJUX21lYW4gPSBtZWFuKFJULCBuYS5ybSA9IFRSVUUpKSAlPiUKICBncm91cF9ieShEaXN0YW5jZSwgcXVhbnRpbGUpICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoYmlhc19ncnBfbWVhbiA9IG1lYW4oYmlhc19tZWFuLCBuYS5ybSA9IFRSVUUpLCAKICAgICAgICAgICAgICAgICAgIGJpYXNfc3RkX2VyciA9IHN0ZC5lcnJvcihiaWFzX21lYW4sIG5hLnJtID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgUlRfZ3JwX21lYW4gPSBtZWFuKFJUX21lYW4sIG5hLnJtID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgUlRfc3RkX2VyciA9IHN0ZC5lcnJvcihSVF9tZWFuLCBuYS5ybSA9IFRSVUUpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBSVF9ncnBfbWVhbiwgeSA9IGJpYXNfZ3JwX21lYW4sIGNvbG9yID0gZmFjdG9yKERpc3RhbmNlKSxncm91cCA9IGZhY3RvcihEaXN0YW5jZSkpKSArIAogIGdlb21fcG9pbnQoKSArIAogIGdlb21fbGluZSgpICsgCiAgZ2VvbV9lcnJvcmJhcmgoYWVzKHhtYXggPSBSVF9ncnBfbWVhbiArIFJUX3N0ZF9lcnIsIHhtaW4gPSBSVF9ncnBfbWVhbiAtIFJUX3N0ZF9lcnIpLCBhbHBoYSA9IDAuNCkgICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWF4ID1iaWFzX2dycF9tZWFuICsgYmlhc19zdGRfZXJyLCB5bWluID0gYmlhc19ncnBfbWVhbiAtIGJpYXNfc3RkX2VyciksIGFscGhhID0gMC40KSArIAogIGxhYnMoeSA9ICdJbndhcmQgQmlhcyAobm9ybSknLCB4ID0gJ1JUIChzKScpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYyhteS5jb2xvcnMyW2MoMSwgMiwgMyldKSwgZ3VpZGUgPSBGQUxTRSkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAuMSwgMC41LCAwLjEpKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMC45NSksIAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJykgKwogIHRoICsgCiAgY29vcmRfY2FwcGVkX2NhcnQoeWxpbSA9IGMoLTEsIDEpLHhsaW0gPSBjKDAuMiwgMC41KSkgCnByaW50KFZTLlF1YW50aWxlLm5vcm0ucGxvdCkKCnNldHdkKCJ+L0Rlc2t0b3AiKQpnZ3NhdmUoc3ByaW50ZignVlNfUXVhbnRpbGVfbm9ybV8lcy5wZGYnLCBzdWJEaXIpLCBwbG90ID0gVlMuUXVhbnRpbGUubm9ybS5wbG90LCBoZWlnaHQgPSAzLCB3aWR0aCA9IDQsICB1bml0cyA9ICJpbiIpCgpgYGAKCgoKCgoKSW1wb3J0IEV4cGVyaW1lbnQgMQpgYGB7cn0KCkUxLmRhdGEgPC0gYXNfdGliYmxlKCByZWFkLmNzdigiL1VzZXJzL2pvbmF0aGFudHNheS9Ecm9wYm94L01PVE9SL3VzZV9kZXBlbmRlbnQvdXNlLWRlcGVuZGVudC1sZWFybmluZy9VRF9FMS5jc3YiLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAnLCcpICU+JQogICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6c2VsZWN0KFNOOlJUYiwgaGFuZF90aGV0YV80MCkpICU+JSBtdXRhdGUoZ3JvdXAgPSAxKSAlPiUKICBtdXRhdGUoRGlzdGFuY2VfcmF3ID0gYXMuZG91YmxlKCBhYnModGkgLSB0cmFpblRndCkpLCAKICAgICAgICAgRGlzdGFuY2UgPSBjYXNlX3doZW4oRGlzdGFuY2VfcmF3ID4gMTgwIH4gYWJzKERpc3RhbmNlX3JhdyAtIDM2MCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEaXN0YW5jZV9yYXcgPCAtMTgwIH4gYWJzKERpc3RhbmNlX3JhdyArIDM2MCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERpc3RhbmNlX3JhdyA8PSAxODAgJiBEaXN0YW5jZV9yYXcgPj0gLTE4MCB+IERpc3RhbmNlX3JhdyksCiAgICAgICAgIENOID0gVE4sIAogICAgICAgICBIYW5kID0gaGFuZF90aGV0YV80MCwgSGFuZGIgPSBOYU4sIFJUYiA9IE5hTikKCkUxLmRhdGEuYmFzZS5vdXQgPC0gYmFzZWxpbmVfc3VidHJhY3QoRTEuZGF0YSwgNzEsIDE0MCwgMCkKRTEuZGF0YSA8LSBFMS5kYXRhLmJhc2Uub3V0W1sxXV0KRTEuZGF0YS5iYXNlIDwtIEUxLmRhdGEuYmFzZS5vdXRbWzJdXQoKCkUxLmRhdGEgPC0gRTEuZGF0YSAlPiUKICBtdXRhdGUoSGFuZF9JQiA9IGNhc2Vfd2hlbih0cmFpblRndCA9PSA2MCAmICh0aSA9PSA5MCAgIHwgdGkgPT0gMTIwICB8IHRpID09IDE1MCApIH4gLUhhbmRiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFpblRndCA9PSA2MCAmICh0aSA9PSAwICAgfCB0aSA9PSAzMCAgfCB0aSA9PSAzMzAgfCB0aSA9PSA2MCkgfiBIYW5kYiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhaW5UZ3QgPT0gMTUwICYgKHRpID09IDE4MCAgfCB0aSA9PSAyMTAgIHwgdGkgPT0gMjQwKSB+IC1IYW5kYiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhaW5UZ3QgPT0gMTUwICYgKHRpID09IDYwICAgfCB0aSA9PSA5MCAgfCB0aSA9PSAxMjAgfCB0aSA9PSAxNTApIH4gSGFuZGIpKQoKCiAgCgpgYGAKCkV4cGVyaW1lbnQgMSBJbmRpdmlkdWFsIERhdGEKYGBge3J9Cgpmb3Ioc2kgaW4gdW5pcXVlKEUxLmRhdGEkU04pKXsKICAKICBncm91cHZhciA8LSB1bmlxdWUoIEUxLmRhdGEkZ3JvdXBbRTEuZGF0YSRTTiA9PSBzaV0gKSAKICBteXltaW4gPC0gbWluKCBFMS5kYXRhJFJUW0UxLmRhdGEkU04gPT0gc2kgJiBFMS5kYXRhJGJsb2NrID49IDMgJiBFMS5kYXRhJGZiaSA9PSAwXSApICsgMC4xCiAgbXl5bWF4IDwtIG1heCggRTEuZGF0YSRSVFtFMS5kYXRhJFNOID09IHNpICYgRTEuZGF0YSRibG9jayA+PSAzICYgRTEuZGF0YSRmYmkgPT0gMF0gKSAtIDAuMQogIAogIGluZC5wbG90IDwtIEUxLmRhdGEgJT4lIAogICAgZmlsdGVyKFNOID09IHNpICYgRGlzdGFuY2UgIT0gMCkgJT4lICAKICAgIGZpbHRlcihibG9jayA+PSAzICYgZmJpID09IDAgKSAlPiUKICAgIGdncGxvdChhZXMoeCA9IFJULCB5ID0gSGFuZF9JQiwgZ3JvdXAgPSBmYWN0b3IoRGlzdGFuY2UpKSkgKyAKICAgIGdlb21fcG9pbnQoYWxwaGEgPSAwLjQsIGFlcyhjb2xvciA9IGZhY3RvcihEaXN0YW5jZSkpKSArIAogICAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xtJywgYWVzKGNvbG9yID0gZmFjdG9yKERpc3RhbmNlKSksIHNpemUgPSAwLjUsIHNlID0gRkFMU0UsIGxpbmV0eXBlPSBncm91cHZhcikgKwogICAgI3N0YXRfY29yKG1ldGhvZCA9ICdwZWFyc29uJykrIAogICAgZmFjZXRfcmVwX3dyYXAoLn5EaXN0YW5jZSwgcmVwZWF0LnRpY2subGFiZWxzID0gVFJVRSwgbmNvbCA9IDQpICsgCiAgICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYyhyb3VuZChteXltaW4sIDEpLCByb3VuZChteXltYXgsIDEpICkpICsKICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKG15LmNvbG9yczJbYygxLCAyLCAzKV0pLCBndWlkZSA9IEZBTFNFKSArIAogICAgbGFicyh5ID0gJ0lud2FyZCBCaWFzICjCsCknLCB4ID0gJ1JUIChzKScsIHN1YnRpdGxlID0gc3ByaW50ZignRXhwIDEgU3ViamVjdCAjJXMnLCBzaSkpICsKICAgIHRoICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAwLjk1KSwgCiAgICAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJykgKwogICAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgtNTAsIDEwMCwgNTApKSArIAogICAgY29vcmRfY2FwcGVkX2NhcnQoeWxpbSA9IGMoLTUwLCAxMDApKSAKICBwcmludChpbmQucGxvdCkgCiAgCiAgZ2dzYXZlKHNwcmludGYoJ0UxX1NVQiVzX0dycCVzX25vdGl0bGVfJXMucGRmJywgc2ksIGdyb3VwdmFyLCBzdWJEaXIpLCBwbG90ID0gaW5kLnBsb3QsIGhlaWdodCA9IDMsIHdpZHRoID0gNCwgIHVuaXRzID0gImluIikKfQoKYGBgCgoKRXhwZXJpbWVudCAxIEdyb3VwIERhdGEKYGBge3J9CgpFMS5pbmQgPC0gRTEuZGF0YSAlPiUKICBmaWx0ZXIoYmxvY2sgPj0gMyAmIGZiaSA9PSAwICkgJT4lCiAgZ3JvdXBfYnkoU04sIERpc3RhbmNlLCBncm91cCkgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShoYW5kX21lYW4gPSBtZWFuKEhhbmRfSUIsIG5hLnJtID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgcnRfbWVhbiA9IG1lYW4oUlQsIG5hLnJtID0gVFJVRSkpCgpFMS5pbmQuYmFzZSA8LSBFMS5kYXRhICU+JQogIGZpbHRlcihibG9jazwgMyAmIGZiaSA9PSAwICkgJT4lCiAgZ3JvdXBfYnkoU04sIERpc3RhbmNlLCBncm91cCkgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShoYW5kX21lYW4gPSBtZWFuKEhhbmRfSUIsIG5hLnJtID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgcnRfbWVhbiA9IG1lYW4oUlQsIG5hLnJtID0gVFJVRSkpCgpFMS5ncnAgPC0gRTEuaW5kICU+JSAKICBncm91cF9ieShEaXN0YW5jZSwgZ3JvdXApICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoaGFuZF9ncnBfbWVhbiA9IG1lYW4oaGFuZF9tZWFuLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICAgICAgICAgaGFuZF9ncnBfc3RkZXJyID0gc3RkLmVycm9yKGhhbmRfbWVhbiwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgICAgICAgIHJ0X2dycF9tZWFuID0gbWVhbihydF9tZWFuLCBuYS5ybSA9IFRSVUUpLCAKICAgICAgICAgICAgICAgICAgIHJ0X2dycF9zdGRlcnIgPSBzdGQuZXJyb3IocnRfbWVhbiwgbmEucm0gPSBUUlVFKSkKCgpFMS5ncnAucGxvdCA8LSBFMS5pbmQgJT4lCiAgZ2dwbG90KGFlcyh4ID0gRGlzdGFuY2UsIHkgPSBoYW5kX21lYW4sIGdyb3VwID0gZ3JvdXApKSArIAogIGdlb21fc2VnbWVudChhZXMoeD0tNSwgeGVuZD05NSwgeSA9IDAsIHllbmQgPSAwKSwgY29sb3IgPSAnbGlnaHRncmV5JykgKwogIHN0YXRfc3VtbWFyeShmdW4gPSAnbWVhbicsIGdlb20gPSAicG9pbnQiKSArIAogIHN0YXRfc3VtbWFyeShmdW4gPSAnbWVhbicsIGdlb20gPSAibGluZSIsIGFlcyhsaW5ldHlwZSA9IGZhY3Rvcihncm91cCkpKSArIAogIHN0YXRfc3VtbWFyeShmdW4uZGF0YSA9ICdtZWFuX3NlJywgZ2VvbSA9ICJlcnJvcmJhciIsIHdpZHRoID0gMikgKyAKICBsYWJzKHkgPSAnSW53YXJkIEJpYXMgKMKwKScsIHggPSAnUHJvYmUgRGlzdGFuY2UgKMKwKScpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYygwLCAzMCwgNjAsIDkwKSkgKwogIHRoICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAwLjk1KSwgCiAgICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAnbm9uZScpICsKICBjb29yZF9jYXBwZWRfY2FydCh5bGltID0gYygtNSwgNDApKQpwcmludChFMS5ncnAucGxvdCkgIAoKZ2dzYXZlKHNwcmludGYoJ0UxX0dyb3VwXyVzLnBkZicsIHN1YkRpciksIHBsb3QgPSBFMS5ncnAucGxvdCwgaGVpZ2h0ID0gMywgd2lkdGggPSA0LCAgdW5pdHMgPSAiaW4iKQoKYGBgCkV4cGVyaW1lbnQgMSBHcm91cCBEYXRhLCB3aXRoIEZpcnN0IFBlYWsgKE9idGFpbmVkIGZyb20gTUNsdXN0KQpgYGB7cn0KCmZpcnN0cGVhayA8LSBzZXROYW1lcyAoIGFzLmRhdGEuZnJhbWUobWF0cml4KG5yb3cgPSA0LCBuY29sID0gNSkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgYygiRGlzdGFuY2UiLCAiZ3JvdXAiLCAiaGFuZF9tZWFuIiwgImhhbmRfdWIiLCAiaGFuZF9sYiIpICkKCmZpcnN0cGVhayREaXN0YW5jZSA8LSBjKDAsIDMwLCA2MCwgOTApCmZpcnN0cGVhayRoYW5kX21lYW4gPC0gYygtMS4xLCAxLjEsIDQuMiwgMy40KQpmaXJzdHBlYWskaGFuZF91YiA8LSBjKC0xLjEsIDIuMywgNS4xLCA0LjIpCmZpcnN0cGVhayRoYW5kX2xiIDwtIGMoLTEuMSwgMC4xLCAzLjIsIDIuNSkKCkUxLmdycE5vSml0LnBsb3QgPC0gRTEuaW5kICU+JQogIGZpbHRlcihncm91cCA9PSAxKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBEaXN0YW5jZSwgeSA9IGhhbmRfbWVhbiwgZ3JvdXAgPSBncm91cCkpICsgCiAgZ2VvbV9zZWdtZW50KGFlcyh4PS01LCB4ZW5kPTk1LCB5ID0gMCwgeWVuZCA9IDApLCBjb2xvciA9ICdsaWdodGdyZXknKSArCiAgc3RhdF9zdW1tYXJ5KGZ1biA9ICdtZWFuJywgZ2VvbSA9ICJwb2ludCIpICsgCiAgc3RhdF9zdW1tYXJ5KGZ1biA9ICdtZWFuJywgZ2VvbSA9ICJsaW5lIiwgYWVzKGxpbmV0eXBlID0gZmFjdG9yKGdyb3VwKSkpICsgCiAgc3RhdF9zdW1tYXJ5KGZ1bi5kYXRhID0gJ21lYW5fc2UnLCBnZW9tID0gImVycm9yYmFyIiwgd2lkdGggPSAyKSArIAogIGdlb21fcG9pbnQoaW5oZXJpdC5hZXMgPSBGQUxTRSwgZGF0YSA9IGZpcnN0cGVhaywgYWVzKHggPSBEaXN0YW5jZSwgeSA9IGhhbmRfbWVhbiksIGNvbG9yID0gImJsYWNrIikrCiAgZ2VvbV9lcnJvcmJhcihpbmhlcml0LmFlcyA9IEZBTFNFLCBkYXRhID0gZmlyc3RwZWFrLCBhZXMoeCA9IERpc3RhbmNlLCB5bWluID0gaGFuZF9sYiwgeW1heCA9IGhhbmRfdWIpLCBjb2xvciA9ICJibGFjayIsIHdpZHRoID0gMikrCiAgZ2VvbV9saW5lKGluaGVyaXQuYWVzID0gRkFMU0UsIGRhdGEgPSBmaXJzdHBlYWssIGFlcyh4ID0gRGlzdGFuY2UsIHkgPSBoYW5kX21lYW4pLCBjb2xvciA9ICJibGFjayIsIGxpbmV0eXBlID0gImRhc2hlZCIpKwogIGxhYnMoeSA9ICdJbndhcmQgQmlhcyAowrApJywgeCA9ICdQcm9iZSBEaXN0YW5jZSAowrApJykgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBjKDAsIDMwLCA2MCwgOTApKSArCiAgdGggKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDAuOTUpLCAKICAgICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJykgKwogIGNvb3JkX2NhcHBlZF9jYXJ0KHlsaW0gPSBjKC01LCA0MCkpCnByaW50KEUxLmdycE5vSml0LnBsb3QpICAKCmdnc2F2ZShzcHJpbnRmKCdFMV9Hcm91cE5vSml0XyVzLnBkZicsIHN1YkRpciksIHBsb3QgPSBFMS5ncnBOb0ppdC5wbG90LCBoZWlnaHQgPSAzLCB3aWR0aCA9IDQsICB1bml0cyA9ICJpbiIpCgpzdGQuZXJyb3IoRTEuaW5kJGhhbmRfbWVhbltFMS5pbmQkZ3JvdXAgPT0gMSAmIEUxLmluZCREaXN0YW5jZSA9PSAwXSkKCmBgYAoKCkV4cGVyaW1lbnQgMSBRdWFudGlsZSBBbmFseXNpcwpgYGB7cn0KCkUxLmluZC5RdWFudGlsZS5kYXRhIDwtIEUxLmRhdGEgJT4lCiAgZmlsdGVyKGJsb2NrID49IDMgJiBmYmkgPT0gMCApICU+JQogIGdyb3VwX2J5KFNOLCBEaXN0YW5jZSwgZ3JvdXApICU+JQogIG11dGF0ZShxdWFudGlsZSA9IG50aWxlKFJULCA1KSkgJT4lCiAgZ3JvdXBfYnkoU04sIERpc3RhbmNlLCBxdWFudGlsZSwgZ3JvdXApICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoYmlhc19tZWFuID0gbWVhbihIYW5kX0lCLCBuYS5ybSA9IFRSVUUpLCAKICAgICAgICAgICAgICAgICAgIFJUX21lYW4gPSBtZWFuKFJULCBuYS5ybSA9IFRSVUUpKQoKCkUxLlF1YW50aWxlLmRhdGEgPC0gRTEuaW5kLlF1YW50aWxlLmRhdGEgJT4lIAogIGdyb3VwX2J5KERpc3RhbmNlLCBxdWFudGlsZSwgZ3JvdXApICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoYmlhc19ncnBfbWVhbiA9IG1lYW4oYmlhc19tZWFuLCBuYS5ybSA9IFRSVUUpLCAKICAgICAgICAgICAgICAgICAgIGJpYXNfc3RkX2VyciA9IHN0ZC5lcnJvcihiaWFzX21lYW4sIG5hLnJtID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgUlRfZ3JwX21lYW4gPSBtZWFuKFJUX21lYW4sIG5hLnJtID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgUlRfc3RkX2VyciA9IHN0ZC5lcnJvcihSVF9tZWFuLCBuYS5ybSA9IFRSVUUpKQoKRTEuUXVhbnRpbGUuZ3JwMS5wbG90IDwtIEUxLlF1YW50aWxlLmRhdGEgJT4lCiAgZmlsdGVyKGdyb3VwID09IDEpICU+JQogIGdncGxvdChhZXMoeCA9IFJUX2dycF9tZWFuLCB5ID0gYmlhc19ncnBfbWVhbiwgY29sb3IgPSBmYWN0b3IoRGlzdGFuY2UpLCBncm91cCA9IGZhY3RvcihEaXN0YW5jZSkpKSArIAogIGdlb21fcG9pbnQoKSArIAogIGdlb21fbGluZSgpICsgCiAgZ2VvbV9lcnJvcmJhcmgoYWVzKHhtYXggPSBSVF9ncnBfbWVhbiArIFJUX3N0ZF9lcnIsIHhtaW4gPSBSVF9ncnBfbWVhbiAtIFJUX3N0ZF9lcnIpLCBhbHBoYSA9IDAuNCkgICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWF4ID1iaWFzX2dycF9tZWFuICsgYmlhc19zdGRfZXJyLCB5bWluID0gYmlhc19ncnBfbWVhbiAtIGJpYXNfc3RkX2VyciksIGFscGhhID0gMC40KSArIAogIGxhYnMoeSA9ICdJbndhcmQgQmlhcyAowrApJywgeCA9ICdSVCAocyknKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ2JsYWNrJywgbXkuY29sb3JzMltjKDEsIDIsIDMpXSksIGd1aWRlID0gRkFMU0UpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLjIsIDAuNiwgMC4xKSkgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDAuOTUpLCAKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAnbm9uZScpICsKICB0aCArIAogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKDAsIDI1LCA1MCwgNzUpKSArCiAgY29vcmRfY2FwcGVkX2NhcnQoeWxpbSA9IGMoLTUsIDc1KSwgeGxpbSA9IGMoMC4xNzUsIDAuNikpIApwcmludChFMS5RdWFudGlsZS5ncnAxLnBsb3QpCgpnZ3NhdmUoc3ByaW50ZignRTFfUXVhbnRpbGVfR3JwMV8lcy5wZGYnLCBzdWJEaXIpLCBwbG90ID0gRTEuUXVhbnRpbGUuZ3JwMS5wbG90LCBoZWlnaHQgPSAzLCB3aWR0aCA9IDQsICB1bml0cyA9ICJpbiIpCgpgYGAKRXhwZXJpbWVudCAxIE5vcm1hbGl6ZWQgUXVpbnRpbGUgQW5hbHlzaXMKYGBge3J9CgpFMS5pbmQuUXVhbnRpbGUubm9ybS5kYXRhIDwtIEUxLmRhdGEgJT4lCiAgZmlsdGVyKGJsb2NrID49IDMgJiBmYmkgPT0gMCAmIGdyb3VwID09IDEpICU+JQogIGdyb3VwX2J5KFNOLCBEaXN0YW5jZSkgJT4lCiAgbXV0YXRlKFNjYWxlX0hhbmRJQiA9IHNjYWxlKEhhbmRfSUIpKSAlPiUKICBtdXRhdGUocXVhbnRpbGUgPSBudGlsZShSVCwgNSkpICU+JQogIGdyb3VwX2J5KFNOLCBEaXN0YW5jZSwgcXVhbnRpbGUpICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoYmlhc19tZWFuID0gbWVhbihTY2FsZV9IYW5kSUIsIG5hLnJtID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgUlRfbWVhbiA9IG1lYW4oUlQsIG5hLnJtID0gVFJVRSkpCgoKRTEuUXVhbnRpbGUubm9ybS5kYXRhIDwtIEUxLmluZC5RdWFudGlsZS5ub3JtLmRhdGEgJT4lIAogIGdyb3VwX2J5KERpc3RhbmNlLCBxdWFudGlsZSkgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShiaWFzX2dycF9tZWFuID0gbWVhbihiaWFzX21lYW4sIG5hLnJtID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgYmlhc19zdGRfZXJyID0gc3RkLmVycm9yKGJpYXNfbWVhbiwgbmEucm0gPSBUUlVFKSwgCiAgICAgICAgICAgICAgICAgICBSVF9ncnBfbWVhbiA9IG1lYW4oUlRfbWVhbiwgbmEucm0gPSBUUlVFKSwgCiAgICAgICAgICAgICAgICAgICBSVF9zdGRfZXJyID0gc3RkLmVycm9yKFJUX21lYW4sIG5hLnJtID0gVFJVRSkpCgpFMS5RdWFudGlsZS5hbGwubm9ybS5wbG90IDwtIEUxLlF1YW50aWxlLm5vcm0uZGF0YSAlPiUKICBmaWx0ZXIoRGlzdGFuY2UgIT0gMCkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gUlRfZ3JwX21lYW4sIHkgPSBiaWFzX2dycF9tZWFuLCBjb2xvciA9IGZhY3RvcihEaXN0YW5jZSksIGdyb3VwID0gZmFjdG9yKERpc3RhbmNlKSkpICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgZ2VvbV9saW5lKCkgKyAKICBnZW9tX2Vycm9yYmFyaChhZXMoeG1heCA9IFJUX2dycF9tZWFuICsgUlRfc3RkX2VyciwgeG1pbiA9IFJUX2dycF9tZWFuIC0gUlRfc3RkX2VyciksIGFscGhhID0gMC40KSAgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltYXggPWJpYXNfZ3JwX21lYW4gKyBiaWFzX3N0ZF9lcnIsIHltaW4gPSBiaWFzX2dycF9tZWFuIC0gYmlhc19zdGRfZXJyKSwgYWxwaGEgPSAwLjQpICsgCiAgbGFicyh5ID0gJ0lud2FyZCBCaWFzIChub3JtKScsIHggPSAnUlQgKHMpJykgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKG15LmNvbG9yczJbYygxLCAyLCAzKV0pLCBndWlkZSA9IEZBTFNFKSArIAogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMC4yLCAwLjcsIDAuMSkpICsgCiAgICB0aCArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMC45NSksIAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJykgCnByaW50KEUxLlF1YW50aWxlLmFsbC5ub3JtLnBsb3QpCgpnZ3NhdmUoc3ByaW50ZignRTFfUXVhbnRpbGVfR3JwMV9Ob3JtXyVzLnBkZicsIHN1YkRpciksIHBsb3QgPSBFMS5RdWFudGlsZS5hbGwubm9ybS5wbG90LCBoZWlnaHQgPSAzLCB3aWR0aCA9IDQsICB1bml0cyA9ICJpbiIpCgpgYGAKCgoKVHJhamVjdG9yeSAKYGBge3IsIGV2YWwgPSBGQUxTRX0KCkUxLnRyYWouZGF0YSA8LSBhc190aWJibGUoIHJlYWQuY3N2KCIvVXNlcnMvam9uYXRoYW50c2F5L0Ryb3Bib3gvTU9UT1IvdXNlX2RlcGVuZGVudC9VRF9XaXRoVHJhai5jc3YiLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAnLCcpKSAlPiUKICBkcGx5cjo6c2VsZWN0KFNOOmh4XzEzOCwgaHlfMTpoeV8xMzgpIAoKCmZvcihzaSBpbiB1bmlxdWUoRTEudHJhai5kYXRhJFNOKSl7CiAgRTEudHJhai5kYXRhLmxvbmcgPC0gRTEudHJhai5kYXRhICU+JSAKICAgIGZpbHRlcihTTiA9PSBzaSkgJT4lCiAgICBnYXRoZXIoQ29uZCwgVmFsdWUsIGh4XzE6aHlfMTM4KSAlPiUKICAgIHNlcGFyYXRlKENvbmQsIGludG8gPSBjKCdYb3JZJywgJ1NhbXBsZXBvaW50Jywgc2VwID0gIl8iKSkgJT4lCiAgICBzcHJlYWQoWG9yWSwgVmFsdWUpCiAgCiAgaW5kLnRyYWoucGxvdCA8LSBFMS50cmFqLmRhdGEubG9uZyAlPiUKICAgIGZpbHRlcihibG9jayA+PSAzLCBmYmkgPT0gMCkgJT4lCiAgICBkcm9wX25hKGh4LCBoeSkgJT4lICAKICAgIGdncGxvdChhZXMoeCA9IGh4LCB5ID1oeSwgY29sb3IgPSBmYWN0b3IodGkpLCBncm91cCA9IFROKSkgKyAKICAgIGdlb21fcGF0aChzaXplID0gMC41KSArCiAgICBjb29yZF9jYXBwZWRfY2FydCh5bGltID0gYygtMTUwLCAxNTApLCB4bGltID0gYygtMTUwLCAxNTApKSArCiAgICB0aCArCiAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDAuOTUpLCAKICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJykgKwogICAgbGFicyh4ID0gJ3ggKG1tKScsIHkgPSAneSAobW0pJykKICAKICBwcmludChpbmQudHJhai5wbG90KQogIAogIGdnc2F2ZShzcHJpbnRmKCdFMV9TVUIlc19UcmFqXyVzLnBkZicsIHNpLCBzdWJEaXIpLCBwbG90ID0gaW5kLnRyYWoucGxvdCwgaGVpZ2h0ID0gMywgd2lkdGggPSA0LCAgdW5pdHMgPSAiaW4iKQogIAp9CgoKYGBgCgoKCgoKCkxvYWQgaW4gRTIgKFJld2FyZCBleHApIEhvbGQgdGltZSA1MDAsIHdpdGggZm9yY2VkIGRlbGF5LgpgYGB7cn0KCkUyLmRhdGEgPC0gYXNfdGliYmxlKCByZWFkLmNzdigiL1VzZXJzL2pvbmF0aGFudHNheS9Ecm9wYm94L01PVE9SL3VzZV9kZXBlbmRlbnQvdXNlLWRlcGVuZGVudC1sZWFybmluZy9VRF9FMi5jc3YiLCBoZWFkZXIgPSBUUlVFLCBzZXAgPSAnLCcpKSAlPiUgCiAgbXV0YXRlKERpc3RhbmNlX3JhdyA9IGFzLmRvdWJsZSggYWJzKHRpIC0gdHJhaW5UZ3QpKSwgRGlzdGFuY2UgPSBjYXNlX3doZW4oRGlzdGFuY2VfcmF3ID4gMTgwIH4gYWJzKERpc3RhbmNlX3JhdyAtIDM2MCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEaXN0YW5jZV9yYXcgPCAtMTgwIH4gYWJzKERpc3RhbmNlX3JhdyArIDM2MCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEaXN0YW5jZV9yYXcgPD0gMTgwICYgRGlzdGFuY2VfcmF3ID49IC0xODAgfiBEaXN0YW5jZV9yYXcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ04gPSBUTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhhbmQgPSBoYW5kX3RoZXRhXzQwLCBIYW5kYiA9IE5hTiwgUlRiID0gTmFOKQoKCkUyLmRhdGEuYmFzZS5vdXQgPC0gYmFzZWxpbmVfc3VidHJhY3QoRTIuZGF0YSwgNzEsIDE0MCwgMCkKRTIuZGF0YSA8LSBFMi5kYXRhLmJhc2Uub3V0W1sxXV0KRTIuZGF0YS5iYXNlIDwtIEUyLmRhdGEuYmFzZS5vdXRbWzJdXQoKIyBmbGlwIHRvIGlud2FyZCBiaWFzIApFMi5kYXRhIDwtIEUyLmRhdGEgJT4lCiAgbXV0YXRlKEhhbmRfSUIgPSBjYXNlX3doZW4odHJhaW5UZ3QgPT0gNjAgJiAodGkgPT0gOTAgICB8IHRpID09IDEyMCAgfCB0aSA9PSAxNTAgKSB+IC1IYW5kYiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhaW5UZ3QgPT0gNjAgJiAodGkgPT0gMCAgIHwgdGkgPT0gMzAgIHwgdGkgPT0gMzMwIHwgdGkgPT0gNjApIH4gSGFuZGIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWluVGd0ID09IDE1MCAmICh0aSA9PSAxODAgIHwgdGkgPT0gMjEwICB8IHRpID09IDI0MCkgfiAtSGFuZGIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWluVGd0ID09IDE1MCAmICh0aSA9PSA2MCAgIHwgdGkgPT0gOTAgIHwgdGkgPT0gMTIwIHwgdGkgPT0gMTUwKSB+IEhhbmRiKSkKCgpgYGAKCgpFeHBlcmltZW50IDIgR3JvdXAgRGF0YSAKYGBge3J9CgpFMi5pbmQgPC0gRTIuZGF0YSAlPiUKICBmaWx0ZXIoYmxvY2sgPj0gMyAmIGZiaSA9PSAwICkgJT4lCiAgZ3JvdXBfYnkoU04sIERpc3RhbmNlLCBncm91cCkgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShoYW5kX21lYW4gPSBtZWFuKEhhbmRfSUIsIG5hLnJtID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgcnRfbWVhbiA9IG1lYW4oUlQsIG5hLnJtID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgbXRfbWVhbiA9IG1lYW4oTVQsIG5hLnJtID0gVFJVRSkpCgpFMi5ncnAgPC0gRTIuaW5kICU+JSAKICBncm91cF9ieShEaXN0YW5jZSwgZ3JvdXApICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoaGFuZF9ncnBfbWVhbiA9IG1lYW4oaGFuZF9tZWFuLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICAgICAgICAgaGFuZF9ncnBfc3RkZXJyID0gc3RkLmVycm9yKGhhbmRfbWVhbiwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgICAgICAgIHJ0X2dycF9tZWFuID0gbWVhbihydF9tZWFuLCBuYS5ybSA9IFRSVUUpLCAKICAgICAgICAgICAgICAgICAgIHJ0X2dycF9zdGRlcnIgPSBzdGQuZXJyb3IocnRfbWVhbiwgbmEucm0gPSBUUlVFKSkKCkUyLmdycEJvdGgucGxvdCA8LSBFMi5pbmQgJT4lCiAgZ2dwbG90KGFlcyh4ID0gRGlzdGFuY2UsIHkgPSBoYW5kX21lYW4sIGdyb3VwID0gZ3JvdXAsIGNvbG9yID0gZ3JvdXApKSArIAogIGdlb21fc2VnbWVudChhZXMoeD0tNSwgeGVuZD05NSwgeSA9IDAsIHllbmQgPSAwKSwgY29sb3IgPSAnbGlnaHRncmV5JykgKwogIHN0YXRfc3VtbWFyeShmdW4gPSAnbWVhbicsIGdlb20gPSAicG9pbnQiKSArIAogIHN0YXRfc3VtbWFyeShmdW4gPSAnbWVhbicsIGdlb20gPSAibGluZSIsIGxpbmV0eXBlID0gMSkgKyAKICBzdGF0X3N1bW1hcnkoZnVuLmRhdGEgPSAnbWVhbl9zZScsIGdlb20gPSAiZXJyb3JiYXIiLCB3aWR0aCA9IDIpICsgCiAgbGFicyh5ID0gJ0lud2FyZCBCaWFzICjCsCknLCB4ID0gJ1Byb2JlIERpc3RhbmNlICjCsCknKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGMoMCwgMzAsIDYwLCA5MCkpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYyggJ2RhcmtncmV5JywgJ2JsYWNrJykpICsKICB0aCArIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMC45NSksIAogICAgICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gJ25vbmUnKSArCiAgY29vcmRfY2FwcGVkX2NhcnQoeWxpbSA9IGMoLTUsIDEwKSkKcHJpbnQoRTIuZ3JwQm90aC5wbG90KSAgCgpnZ3NhdmUoc3ByaW50ZignRTJfR3JvdXBCb3RoXyVzLnBkZicsIHN1YkRpciksIHBsb3QgPSBFMi5ncnBCb3RoLnBsb3QsIGhlaWdodCA9IDMsIHdpZHRoID0gNCwgIHVuaXRzID0gImluIikKCmBgYAoKCkV4cGVyaW1lbnQgMjogUXVhbnRpbGUgQW5hbHlzaXMgQ29tYmluZWQKYGBge3J9CgpFMi5kYXRhIDwtIEUyLmRhdGEgJT4lIG11dGF0ZShTTl9uZXcgPSBpZmVsc2UoZ3JvdXAgPT0gIlIiLCBTTiArIDk5OSwgU04pKQoKRTIuUXVhbnRpbGUuY29tYi5kYXRhIDwtRTIuZGF0YSAlPiUKICBmaWx0ZXIoYmxvY2sgPj0gMyAmIGZiaSA9PSAwICkgJT4lCiAgZ3JvdXBfYnkoU05fbmV3LCBEaXN0YW5jZSkgJT4lCiAgbXV0YXRlKHF1YW50aWxlID0gbnRpbGUoUlQsIDUpKSAlPiUKICBncm91cF9ieShTTl9uZXcsIERpc3RhbmNlLCBxdWFudGlsZSkgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShiaWFzX21lYW4gPSBtZWFuKEhhbmRfSUIsIG5hLnJtID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgUlRfbWVhbiA9IG1lYW4oUlQsIG5hLnJtID0gVFJVRSkpICU+JQogIGdyb3VwX2J5KERpc3RhbmNlLCBxdWFudGlsZSkgJT4lCiAgZHBseXI6OnN1bW1hcmlzZShiaWFzX2dycF9tZWFuID0gbWVhbihiaWFzX21lYW4sIG5hLnJtID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgYmlhc19zdGRfZXJyID0gc3RkLmVycm9yKGJpYXNfbWVhbiwgbmEucm0gPSBUUlVFKSwgCiAgICAgICAgICAgICAgICAgICBSVF9ncnBfbWVhbiA9IG1lYW4oUlRfbWVhbiwgbmEucm0gPSBUUlVFKSwgCiAgICAgICAgICAgICAgICAgICBSVF9zdGRfZXJyID0gc3RkLmVycm9yKFJUX21lYW4sIG5hLnJtID0gVFJVRSkpCgpFMi5RdWFudGlsZS5jb21iLnBsb3QgPC0gRTIuUXVhbnRpbGUuY29tYi5kYXRhICU+JQogIGdncGxvdChhZXMoeCA9IFJUX2dycF9tZWFuLCB5ID0gYmlhc19ncnBfbWVhbiwgY29sb3IgPSBmYWN0b3IoRGlzdGFuY2UpLCBncm91cCA9IGZhY3RvcihEaXN0YW5jZSkpKSArIAogIGdlb21fcG9pbnQoKSArIAogIGdlb21fbGluZSgpICsgCiAgZ2VvbV9lcnJvcmJhcmgoYWVzKHhtYXggPSBSVF9ncnBfbWVhbiArIFJUX3N0ZF9lcnIsIHhtaW4gPSBSVF9ncnBfbWVhbiAtIFJUX3N0ZF9lcnIpLCBhbHBoYSA9IDAuNCkgICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWF4ID1iaWFzX2dycF9tZWFuICsgYmlhc19zdGRfZXJyLCB5bWluID0gYmlhc19ncnBfbWVhbiAtIGJpYXNfc3RkX2VyciksIGFscGhhID0gMC40KSArIAogIGxhYnMoeSA9ICdJbndhcmQgQmlhcyAowrApJywgeCA9ICdSVCAocyknKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ2JsYWNrJywgbXkuY29sb3JzMltjKDEsIDIsIDMpXSksIGd1aWRlID0gRkFMU0UpICsgCiAgI3NjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMC4yLCAwLjcsIDAuMSkpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCAxMCwgNSkpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAwLjk1KSwgCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gJ25vbmUnKSArCiAgdGggKyAKICBjb29yZF9jYXBwZWRfY2FydCh5bGltID0gYygtMiwgMTApKSAKcHJpbnQoRTIuUXVhbnRpbGUuY29tYi5wbG90KQoKZ2dzYXZlKHNwcmludGYoJ0UyX1F1YW50aWxlX0NvbWJfJXMucGRmJywgc3ViRGlyKSwgcGxvdCA9IEUyLlF1YW50aWxlLmNvbWIucGxvdCwgaGVpZ2h0ID0gMywgd2lkdGggPSA0LCAgdW5pdHMgPSAiaW4iKQoKYGBgCgpgYGB7cn0KCmZvcihzaSBpbiB1bmlxdWUoRTIuZGF0YSRTTikpewogIAogIHByby5kYXRhIDwtIEUyLmRhdGEgJT4lIAogICAgZmlsdGVyKFNOID09IHNpKSAlPiUgIAogICAgZmlsdGVyKGJsb2NrID49IDMgJiBmYmkgPT0gMCAmIERpc3RhbmNlID4gMCAmIFJUIDwgMykKICAKICBncm91cHZhciA8LSAxCiAgbXl5bWluIDwtIG1pbiggcHJvLmRhdGEkUlRbcHJvLmRhdGEkU04gPT0gc2kgJiBwcm8uZGF0YSRibG9jayA+PSAzICYgcHJvLmRhdGEkZmJpID09IDBdLCBuYS5ybSA9IFRSVUUpICsgMC4yCiAgbXl5bWF4IDwtIG1heCggcHJvLmRhdGEkUlRbcHJvLmRhdGEkU04gPT0gc2kgJiBwcm8uZGF0YSRibG9jayA+PSAzICYgcHJvLmRhdGEkZmJpID09IDBdLCBuYS5ybSA9IFRSVUUpIC0gMC4yCiAgCiAgaW5kLnBsb3QgPC0gcHJvLmRhdGEgJT4lCiAgICBnZ3Bsb3QoYWVzKHggPSBSVCwgeSA9IEhhbmRfSUIsIGdyb3VwID0gZmFjdG9yKERpc3RhbmNlKSkpICsgCiAgICBnZW9tX3BvaW50KGFscGhhID0gMC40LCBhZXMoY29sb3IgPSBmYWN0b3IoRGlzdGFuY2UpKSkgKyAKICAgIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIGFlcyhjb2xvciA9IGZhY3RvcihEaXN0YW5jZSkpLCBzaXplID0gMC41LCBzZSA9IEZBTFNFLCBsaW5ldHlwZT0gZ3JvdXB2YXIpICsgCiAgICBmYWNldF9yZXBfd3JhcCgufkRpc3RhbmNlLCByZXBlYXQudGljay5sYWJlbHMgPSBUUlVFLCBuY29sID0gNCkgKyAKICAgICNzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYyhyb3VuZChteXltaW4sIDEpLCByb3VuZChteXltYXgsIDEpICkpICsKICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKG15LmNvbG9yczJbYygxLCAyLCAzKV0pLCBndWlkZSA9IEZBTFNFKSArIAogICAgbGFicyh5ID0gJ0lud2FyZCBCaWFzICjCsCknLCB4ID0gJ1JUIChzKScsIHN1YnRpdGxlID0gc3ByaW50ZignRXhwIDIgU3ViamVjdCAjJXMnLCBzaSkpICsgCiAgICB0aCArIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMC45NSksIAogICAgICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAnbm9uZScpICsKICAgIGNvb3JkX2NhcHBlZF9jYXJ0KHlsaW0gPSBjKC0yNSwgMjUpKSAKICBwcmludChpbmQucGxvdCkgCiAgCiAgZ2dzYXZlKHNwcmludGYoJ2FFMl9TVUIlc19HcnAlc18lcy5wZGYnLCBzaSwgZ3JvdXB2YXIsIHN1YkRpciksIHBsb3QgPSBpbmQucGxvdCwgaGVpZ2h0ID0gMywgd2lkdGggPSA0LCAgdW5pdHMgPSAiaW4iKQogIAp9CgpgYGAKCgoKYGBge3J9CgpyZXdhcmRjZGYgPC0gRTIuZGF0YSAlPiUKICBmaWx0ZXIoYmxvY2sgPj0gMyAmIERpc3RhbmNlID09IDApICU+JQogIGdncGxvdChhZXMoeCA9IGFicyhoYW5kX3RoZXRhKSwgYWxwaGEgPSBncm91cCkpICsgCiAgc3RhdF9lY2RmKGdlb20gPSAic3RlcCIpICsgCiAgc2NhbGVfYWxwaGFfbWFudWFsKHZhbHVlcyA9IGMoMC4yLCAxKSwgZ3VpZGUgPSBGQUxTRSkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDQwKSkgKwogIGxhYnMoeSA9ICdDdW11bGF0aXZlIFByb2JhYmlsaXR5JywgeCA9ICdFcnJvciAowrApJykgKwogIHRoCnByaW50KHJld2FyZGNkZikKCmdnc2F2ZShzcHJpbnRmKCdFMl9yZXdhcmRjZGZfJXMucGRmJywgc3ViRGlyKSwgcGxvdCA9IHJld2FyZGNkZiwgaGVpZ2h0ID0gMywgd2lkdGggPSAzLCAgdW5pdHMgPSAiaW4iKQoKCgpgYGAKCgpFMSBCaW1vZGFsCmBgYHtyfQoKRTEuZGF0YSREaXN0YW5jZSA8LSBmYWN0b3IoRTEuZGF0YSREaXN0YW5jZSwgbGV2ZWxzID0gYygiMCIsICIzMCIsICI2MCIsICI5MCIpKQpFMS5kYXRhLmRlbnNpdHkgPC0gRTEuZGF0YSAlPiUKICBmaWx0ZXIoYmxvY2sgPiAyKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBIYW5kX0lCLCBmaWxsID0gRGlzdGFuY2UpKSArCiAgZ2VvbV9kZW5zaXR5KGFscGhhID0gMC41KSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgtMzAsIDEyMCwgMzApKSArCiAgZmFjZXRfcmVwX3dyYXAoRGlzdGFuY2V+LiwgbmNvbCA9IDQsIHJlcGVhdC50aWNrLmxhYmVscyA9IFRSVUUpICsgCiAgdGggKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygnYmxhY2snLCBteS5jb2xvcnMyW2MoMSwgMiwgMyldKSwgZ3VpZGUgPSBGQUxTRSkgKwogIGNvb3JkX2NhcHBlZF9jYXJ0KHhsaW0gPSBjKC0zMCwgMTIwKSkgKwogIGxhYnMoeCA9ICJIZWFkaW5nIEFuZ2xlICjCsCkiLCB5ID0gIlByb2JhYmlsaXR5IERlbnNpdHkiKQpwcmludChFMS5kYXRhLmRlbnNpdHkpCgojc2V0d2QoIn4vRGVza3RvcCIpCmdnc2F2ZShzcHJpbnRmKCdFMV9EZW5zaXR5XyVzLnBkZicsIHN1YkRpciksIHBsb3QgPSBFMS5kYXRhLmRlbnNpdHksIGhlaWdodCA9IDMsIHdpZHRoID0gMTAuNSwgIHVuaXRzID0gImluIikKCmBgYAoKYGBge3J9CgpWUy5kYXRhLmFsbHByb2JlcyA8LSAgYXNfdGliYmxlKCByZWFkLmNzdigiL1VzZXJzL2pvbmF0aGFudHNheS9Ecm9wYm94L01PVE9SL3VzZV9kZXBlbmRlbnQvdXNlLWRlcGVuZGVudC1sZWFybmluZy9WZXJzdHluZW5TYWJlczIwMTEuY3N2IiwgaGVhZGVyID0gVFJVRSwgc2VwID0gJywnKSkgJT4lIG11dGF0ZShCaWFzID0gSGFuZF9JQikKClZTLmRhdGEuZGVuc2l0eSA8LSBWUy5kYXRhLmFsbHByb2JlcyAlPiUKICBnZ3Bsb3QoYWVzKHggPSBIYW5kX0lCLCBmaWxsID0gZmFjdG9yKERpc3RhbmNlKSkpICArCiAgZ2VvbV9kZW5zaXR5KGFscGhhID0gMC41KSArCiAgIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoLTMwLCAxMjAsIDMwKSwgbGltaXRzID0gYygtNjAsIDE1MCkpICsKICBmYWNldF9yZXBfd3JhcChEaXN0YW5jZX4uLCBuY29sID0gNCwgcmVwZWF0LnRpY2subGFiZWxzID0gVFJVRSkgKyAKICB0aCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCdibGFjaycsIG15LmNvbG9yczJbYygxLCAyLCAzKV0pLCBndWlkZSA9IEZBTFNFKSArCiAgbGFicyh4ID0gIkhlYWRpbmcgQW5nbGUgKMKwKSIsIHkgPSAiUHJvYmFiaWxpdHkgRGVuc2l0eSIpCnByaW50KFZTLmRhdGEuZGVuc2l0eSkKCnNldHdkKCJ+L0Rlc2t0b3AiKQojZ2dzYXZlKHNwcmludGYoJ1ZTX0RlbnNpdHlfJXMucGRmJywgc3ViRGlyKSwgcGxvdCA9IFZTLmRhdGEuZGVuc2l0eSwgaGVpZ2h0ID0gMywgd2lkdGggPSAxMC41LCAgdW5pdHMgPSAiaW4iKQoKYGBgCgoKRTIgQmltb2RhbApgYGB7cn0KCkUyLmRhdGEkRGlzdGFuY2UgPC0gZmFjdG9yKEUyLmRhdGEkRGlzdGFuY2UsIGxldmVscyA9IGMoIjAiLCAiMzAiLCAiNjAiLCAiOTAiKSkKRTIuZGF0YS5kZW5zaXR5IDwtIEUyLmRhdGEgJT4lCiAgZmlsdGVyKGJsb2NrID4gMikgJT4lCiAgZ2dwbG90KGFlcyh4ID0gSGFuZF9JQiwgZmlsbCA9IERpc3RhbmNlKSkgKwogICNnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDUpICsKICBnZW9tX2RlbnNpdHkoYWxwaGEgPSAwLjUpICsKICAjZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gOTAsIGxpbmV0eXBlID0gImRvdHRlZCIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKC0zMCwgMTIwLCAzMCksIGxpbWl0cyA9IGMoLTYwLCAxNTApKSArCiAgY29vcmRfY2FwcGVkX2NhcnQoeGxpbSA9IGMoLTMwLDEyMCkpICsKICBmYWNldF9yZXBfd3JhcChEaXN0YW5jZX4uLCBuY29sID0gNCwgcmVwZWF0LnRpY2subGFiZWxzID0gVFJVRSkgKyAKICB0aCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCdibGFjaycsIG15LmNvbG9yczJbYygxLCAyLCAzKV0pLCBndWlkZSA9IEZBTFNFKSArCiAgbGFicyh4ID0gIkhlYWRpbmcgQW5nbGUgKMKwKSIsIHkgPSAiUHJvYmFiaWxpdHkgRGVuc2l0eSIpCnByaW50KEUyLmRhdGEuZGVuc2l0eSkKCiNzZXR3ZCgifi9EZXNrdG9wIikKZ2dzYXZlKHNwcmludGYoJ0UyX0RlbnNpdHlfJXMucGRmJywgc3ViRGlyKSwgcGxvdCA9IEUyLmRhdGEuZGVuc2l0eSwgaGVpZ2h0ID0gMywgd2lkdGggPSAxMC41LCAgdW5pdHMgPSAiaW4iKQoKCmBgYAoKRTEgbW9kZWxpbmcKYGBge3J9CgpFMS5kYXRhJERpc3RhbmNlIDwtIGZhY3RvcihFMS5kYXRhJERpc3RhbmNlLCBsZXZlbHMgPSBjKDAsIDkwLCAzMCwgNjApKQpFMS5kYXRhLm1vZCA8LSBFMS5kYXRhICU+JSBmaWx0ZXIoZ3JvdXAgPT0gMSAmIGJsb2NrID49IDMpICU+JSBncm91cF9ieShTTiwgRGlzdGFuY2UpICU+JSBtdXRhdGUoc2NhbGVfSGFuZF9JQiA9IHNjYWxlKEhhbmRfSUIpKQpteUUxbW9kIDwtIGxtZXIoc2NhbGVfSGFuZF9JQiB+IFJUICogZmFjdG9yKERpc3RhbmNlKSArICgxIHxTTiksIGRhdGEgPSBFMS5kYXRhLm1vZCAlPiUgZmlsdGVyKERpc3RhbmNlICE9ICIwIikpCnN1bW1hcnkobXlFMW1vZCkKQW5vdmEobXlFMW1vZCwgdHlwZSA9ICdJSUknKQpldGFfc3EobXlFMW1vZCkKCmBgYAoKClZTIG1vZGVsaW5nCmBgYHtyfQoKVlMuZGF0YSREaXN0YW5jZSA8LSBmYWN0b3IoVlMuZGF0YSREaXN0YW5jZSwgbGV2ZWxzID0gYygwLCAzMCwgNjAsIDkwKSkKVlMuZGF0YSA8LSBWUy5kYXRhICU+JSBncm91cF9ieShTTiwgRGlzdGFuY2UpICU+JSBtdXRhdGUoc2NhbGVfaGFuZF9JQiA9IHNjYWxlKEhhbmRfSUIpKQpteVZTbW9kIDwtIGxtZXIoSGFuZF9JQiB+ICBSVCAqIGZhY3RvcihEaXN0YW5jZSkgKyAoMXxTTiksIGRhdGEgPSBWUy5kYXRhKQpzdW1tYXJ5KG15VlNtb2QpCkFub3ZhKG15VlNtb2QsIHR5cGUgPSAnSUlJJykKZXRhX3NxKG15VlNtb2QpCgpgYGAKCkUyIG1vZGVsaW5nCmBgYHtyfQoKRTIuZGF0YSREaXN0YW5jZSA8LSBmYWN0b3IoRTIuZGF0YSREaXN0YW5jZSwgbGV2ZWxzID0gYygwLCAzMCwgNjAsIDkwKSkKbXlFMm1vZCA8LSBsbWVyKEhhbmRfSUIgfiBSVCpEaXN0YW5jZSArIChTTl9uZXd8IGdyb3VwKSwgZGF0YSA9IEUyLmRhdGEgJT4lIGZpbHRlcihibG9jayA+PSAzICYgZmJpID09IDAgKSkKc3VtbWFyeShteUUybW9kKQpBbm92YShteUUybW9kLCB0eXBlID0gJ0lJSScpCmV0YV9zcShteUUybW9kKQoKYGBgCgoKTWFrZSBvdmVybGFwcGluZyBkaXN0cmlidXRpb24KYGBge3J9CgpFMS5kYXRhJERpc3RhbmNlIDwtIGZhY3RvcihFMS5kYXRhJERpc3RhbmNlLCBsZXZlbHMgPSBjKCIwIiwgIjMwIiwgIjYwIiwgIjkwIikpCkUxLmRhdGEuZGVuc2l0eS5zdWIgPC0gRTEuZGF0YSAlPiUKICBmaWx0ZXIoYmxvY2sgPiAyKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBIYW5kX0lCLCBmaWxsID0gRGlzdGFuY2UsIGdyb3VwID0gZmFjdG9yKFNOKSkpICsKICAjZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSA1KSArCiAgI2dlb21fdmxpbmUoeGludGVyY2VwdCA9IDkwLCBsaW5ldHlwZSA9ICJkb3R0ZWQiKSArCiAgZ2VvbV9kZW5zaXR5KGFscGhhID0gMC4xLCBzaXplID0gMC4xKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgtMzAsIDEyMCwgMzApKSArCiAgZmFjZXRfcmVwX3dyYXAoRGlzdGFuY2V+LiwgbmNvbCA9IDQsIHJlcGVhdC50aWNrLmxhYmVscyA9IFRSVUUpICsgCiAgdGggKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygnYmxhY2snLCBteS5jb2xvcnMyW2MoMSwgMiwgMyldKSwgZ3VpZGUgPSBGQUxTRSkgKwogIGNvb3JkX2NhcHBlZF9jYXJ0KHhsaW0gPSBjKC0zMCwgMTIwKSkgKwogIGxhYnMoeCA9ICJIZWFkaW5nIEFuZ2xlICjCsCkiLCB5ID0gIlByb2JhYmlsaXR5IERlbnNpdHkiKQpwcmludChFMS5kYXRhLmRlbnNpdHkuc3ViKQoKZ2dzYXZlKHNwcmludGYoJ0UxX2luZF9kZW5zaXR5XyVzLnBkZicsIHN1YkRpciksIHBsb3QgPSBFMS5kYXRhLmRlbnNpdHkuc3ViLCBoZWlnaHQgPSAzLCB3aWR0aCA9IDEwLjUsICB1bml0cyA9ICJpbiIpCgpFMi5kYXRhJERpc3RhbmNlIDwtIGZhY3RvcihFMi5kYXRhJERpc3RhbmNlLCBsZXZlbHMgPSBjKCIwIiwgIjMwIiwgIjYwIiwgIjkwIikpCkUyLmRhdGEuZGVuc2l0eS5zdWIgPC0gRTIuZGF0YSAlPiUKICBmaWx0ZXIoYmxvY2sgPiAyKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBIYW5kX0lCLCBmaWxsID0gRGlzdGFuY2UsIGdyb3VwID0gZmFjdG9yKFNOKSkpICsKICAjZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSA1KSArCiAgZ2VvbV9kZW5zaXR5KGFscGhhID0gMC4xLCBzaXplID0gMC4xKSArCiAgI2dlb21fdmxpbmUoeGludGVyY2VwdCA9IDkwLCBsaW5ldHlwZSA9ICJkb3R0ZWQiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgtMzAsIDEyMCwgMzApLCBsaW1pdHMgPSBjKC02MCwgMTUwKSkgKwogIGNvb3JkX2NhcHBlZF9jYXJ0KHhsaW0gPSBjKC0zMCwxMjApKSArCiAgZmFjZXRfcmVwX3dyYXAoRGlzdGFuY2V+LiwgbmNvbCA9IDQsIHJlcGVhdC50aWNrLmxhYmVscyA9IFRSVUUpICsgCiAgdGggKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygnYmxhY2snLCBteS5jb2xvcnMyW2MoMSwgMiwgMyldKSwgZ3VpZGUgPSBGQUxTRSkgKwogIGxhYnMoeCA9ICJIZWFkaW5nIEFuZ2xlICjCsCkiLCB5ID0gIlByb2JhYmlsaXR5IERlbnNpdHkiKQpwcmludChFMi5kYXRhLmRlbnNpdHkuc3ViKQoKZ2dzYXZlKHNwcmludGYoJ0UyX2luZF9kZW5zaXR5XyVzLnBkZicsIHN1YkRpciksIHBsb3QgPSBFMi5kYXRhLmRlbnNpdHkuc3ViLCBoZWlnaHQgPSAzLCB3aWR0aCA9IDEwLjUsICB1bml0cyA9ICJpbiIpCgoKYGBgCgoKYGBge3J9CgpgYGAKCgo=